diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index ed12e1e9c1..8537fbf8fe 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -89,6 +89,7 @@ BLXNS bmcr BMSR BPDG +BPIALL brgintclr brginten brgintstat @@ -920,6 +921,7 @@ Picovolts PIDEVAD pidr PIDR +PINSEL PIOA PKHBT pkhtb @@ -1263,6 +1265,7 @@ STLIDMPUSR STLIMPUOR STLNVICACTVOR STLNVICPENDOR +Storex strbt STRBT strexb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba6a8c1660..b78ea87ba3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,7 +128,7 @@ jobs: path: ./ formatting: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Check formatting @@ -406,7 +406,7 @@ jobs: - name: Set up CBMC runner uses: FreeRTOS/CI-CD-Github-Actions/set_up_cbmc_runner@main with: - cbmc_version: "5.95.1" + cbmc_version: "6.3.1" - env: stepName: Install Dependencies diff --git a/README.md b/README.md index eda390d7fe..21d4f6f7fa 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,12 @@ This library has undergone static code analysis and checks for compliance with t ## Getting started The easiest way to use version 4.0.0 and later of FreeRTOS-Plus-TCP is to refer the Getting started Guide (found [here](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/GettingStarted.md)) -Another way is to start with the pre-configured IPv4 Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator)) or IPv6 Multi-endpoint Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo)). That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the [FreeRTOS Kernel Quick Start Guide](https://www.freertos.org/FreeRTOS-quick-start-guide.html) for detailed instructions and other useful links. +Another way is to start with the pre-configured IPv4 Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator)) or IPv6 Multi-endpoint Windows Simulator demo (found in [this directory](https://github.com/FreeRTOS/FreeRTOS/tree/main/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_IPv6_Demo/IPv6_Multi_WinSim_demo)). That way you will have the correct FreeRTOS source files included, and the correct include paths configured. Once a demo application is building and executing you can remove the demo application files, and start to add in your own application source files. See the [FreeRTOS Kernel Quick Start Guide](https://www.freertos.org/Documentation/01-FreeRTOS-quick-start/01-Beginners-guide/02-Quick-start-guide) for detailed instructions and other useful links. -Additionally, for FreeRTOS-Plus-TCP source code organization refer to the [Documentation](http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html), and [API Reference](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html). +Additionally, for FreeRTOS-Plus-TCP source code organization refer to the [Documentation](http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html), and [API Reference](https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/01-FreeRTOS-plus-TCP-APIs). ### Getting help -If you have any questions or need assistance troubleshooting your FreeRTOS project, we have an active community that can help on the [FreeRTOS Community Support Forum](https://forums.freertos.org). Please also refer to [FAQ](http://www.freertos.org/FAQHelp.html) for frequently asked questions. +If you have any questions or need assistance troubleshooting your FreeRTOS project, we have an active community that can help on the [FreeRTOS Community Support Forum](https://forums.freertos.org). Please also refer to [FAQ](https://www.freertos.org/Why-FreeRTOS/FAQs) for frequently asked questions. Also see the [Submitting a bugs/feature request](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/.github/CONTRIBUTING.md#submitting-a-bugsfeature-request) section of CONTRIBUTING.md for more details. @@ -86,7 +86,7 @@ git submodule update --checkout --init --recursive tools/CMock test/FreeRTOS-Ker ``` ## Porting -The porting guide is available on [this page](http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_Porting.html). +The porting guide is available on [this page](https://www.freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/01-FreeRTOS_TCP_Porting). ## Repository structure This repository contains the FreeRTOS-Plus-TCP repository and a number of supplementary libraries for testing/PR Checks. diff --git a/readme.txt b/readme.txt index 65e5e2b19d..62f2df8465 100644 --- a/readme.txt +++ b/readme.txt @@ -7,7 +7,7 @@ A description of the source code organisation is available on: http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html The porting guide is available on: -http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_Porting.html +https://www.freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/01-FreeRTOS_TCP_Porting License information is available on: http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_Plus_TCP_License.html diff --git a/source/FreeRTOS_DHCP.c b/source/FreeRTOS_DHCP.c index 87a66eb205..df187e94fa 100644 --- a/source/FreeRTOS_DHCP.c +++ b/source/FreeRTOS_DHCP.c @@ -81,7 +81,7 @@ /** * @brief The number of end-points that are making use of the UDP-socket. */ - static BaseType_t xDHCPSocketUserCount = 0; + _static BaseType_t xDHCPSocketUserCount = 0; /* * Generate a DHCP discover message and send it on the DHCP socket. @@ -881,7 +881,7 @@ configASSERT( xSocketValid( xDHCPv4Socket ) == pdTRUE ); /* MISRA Ref 11.4.1 [Socket error and integer to pointer conversion] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-114 */ /* coverity[misra_c_2012_rule_11_4_violation] */ if( xSocketValid( xDHCPv4Socket ) == pdTRUE ) { diff --git a/source/FreeRTOS_DHCPv6.c b/source/FreeRTOS_DHCPv6.c index ef3d4c90ff..c5f0a1d233 100644 --- a/source/FreeRTOS_DHCPv6.c +++ b/source/FreeRTOS_DHCPv6.c @@ -85,11 +85,11 @@ ( ( ( uint32_t ) 1U ) << DHCPv6_Option_Server_Identifier ) ) /** @brief The UDP socket which is shared by all end-points that need DHCPv6. */ -static Socket_t xDHCPv6Socket; +_static Socket_t xDHCPv6Socket; /** @brief A reference count makes sure that the UDP socket will be deleted when it * is not used anymore. */ -static BaseType_t xDHCPv6SocketUserCount; +_static BaseType_t xDHCPv6SocketUserCount; static BaseType_t prvIsOptionLengthValid( uint16_t usOption, size_t uxOptionLength, @@ -151,7 +151,7 @@ static BaseType_t prvDHCPv6_handleOption( struct xNetworkEndPoint * pxEndPoint, /** * @brief DHCP IPv6 message object */ -static DHCPMessage_IPv6_t xDHCPMessage; +_static DHCPMessage_IPv6_t xDHCPMessage; /** * @brief Get the DHCP state from a given endpoint. @@ -1500,7 +1500,13 @@ static BaseType_t prvDHCPv6Analyse( struct xNetworkEndPoint * pxEndPoint, } else { - ulOptionsReceived |= ( ( ( uint32_t ) 1U ) << usOption ); + /* ulOptionsReceived has only 32-bits, it's not allowed to shift more than 32-bits on it. */ + if( usOption < 32 ) + { + /* Store the option by bit-map only if it's less than 32. */ + ulOptionsReceived |= ( ( ( uint32_t ) 1U ) << usOption ); + } + xReady = prvDHCPv6_handleOption( pxEndPoint, usOption, &( xSet ), pxDHCPMessage, &( xMessage ) ); } diff --git a/source/FreeRTOS_DNS_Cache.c b/source/FreeRTOS_DNS_Cache.c index 092756e9a2..02d3472ee4 100644 --- a/source/FreeRTOS_DNS_Cache.c +++ b/source/FreeRTOS_DNS_Cache.c @@ -448,10 +448,9 @@ /* Add or update the item. */ if( strlen( pcName ) < ( size_t ) ipconfigDNS_CACHE_NAME_LENGTH ) { - ( void ) strncpy( xDNSCache[ uxFreeEntry ].pcName, pcName, ipconfigDNS_CACHE_NAME_LENGTH ); + ( void ) strncpy( xDNSCache[ uxFreeEntry ].pcName, pcName, strlen( pcName ) ); ( void ) memcpy( &( xDNSCache[ uxFreeEntry ].xAddresses[ 0 ] ), pxIP, sizeof( *pxIP ) ); - xDNSCache[ uxFreeEntry ].ulTTL = ulTTL; xDNSCache[ uxFreeEntry ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds; #if ( ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY > 1 ) diff --git a/source/FreeRTOS_DNS_Parser.c b/source/FreeRTOS_DNS_Parser.c index 5184fdabe0..a35c7fdbde 100644 --- a/source/FreeRTOS_DNS_Parser.c +++ b/source/FreeRTOS_DNS_Parser.c @@ -484,31 +484,30 @@ LLMNRAnswer_t * pxAnswer; uint8_t * pucNewBuffer = NULL; size_t uxExtraLength; + size_t uxDataLength = uxBufferLength + + sizeof( UDPHeader_t ) + + sizeof( EthernetHeader_t ) + + uxIPHeaderSizePacket( pxNetworkBuffer ); - if( xBufferAllocFixedSize == pdFALSE ) - { - size_t uxDataLength = uxBufferLength + - sizeof( UDPHeader_t ) + - sizeof( EthernetHeader_t ) + - uxIPHeaderSizePacket( pxNetworkBuffer ); - - #if ( ipconfigUSE_IPv6 != 0 ) - if( xSet.usType == dnsTYPE_AAAA_HOST ) - { - uxExtraLength = sizeof( LLMNRAnswer_t ) + ipSIZE_OF_IPv6_ADDRESS - sizeof( pxAnswer->ulIPAddress ); - } - else - #endif /* ( ipconfigUSE_IPv6 != 0 ) */ - #if ( ipconfigUSE_IPv4 != 0 ) - { - uxExtraLength = sizeof( LLMNRAnswer_t ); - } - #else /* ( ipconfigUSE_IPv4 != 0 ) */ + #if ( ipconfigUSE_IPv6 != 0 ) + if( xSet.usType == dnsTYPE_AAAA_HOST ) { - /* do nothing, coverity happy */ + uxExtraLength = sizeof( LLMNRAnswer_t ) + ipSIZE_OF_IPv6_ADDRESS - sizeof( pxAnswer->ulIPAddress ); } - #endif /* ( ipconfigUSE_IPv4 != 0 ) */ + else + #endif /* ( ipconfigUSE_IPv6 != 0 ) */ + #if ( ipconfigUSE_IPv4 != 0 ) + { + uxExtraLength = sizeof( LLMNRAnswer_t ); + } + #else /* ( ipconfigUSE_IPv4 != 0 ) */ + { + /* do nothing, coverity happy */ + } + #endif /* ( ipconfigUSE_IPv4 != 0 ) */ + if( xBufferAllocFixedSize == pdFALSE ) + { /* Set the size of the outgoing packet. */ pxNetworkBuffer->xDataLength = uxDataLength; pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, @@ -537,7 +536,17 @@ } else { - pucNewBuffer = &( pxNetworkBuffer->pucEthernetBuffer[ uxUDPOffset ] ); + /* When xBufferAllocFixedSize is TRUE, check if the buffer size is big enough to + * store the answer. */ + if( ( uxDataLength + uxExtraLength ) <= ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) + { + pucNewBuffer = &( pxNetworkBuffer->pucEthernetBuffer[ uxUDPOffset ] ); + } + else + { + /* Just to indicate that the message may not be answered. */ + pxNetworkBuffer = NULL; + } } if( ( pxNetworkBuffer != NULL ) ) @@ -1093,7 +1102,7 @@ /* Define the ASCII value of the capital "A". */ const uint8_t ucCharA = ( uint8_t ) 0x41U; - ucByte = ( uint8_t ) ( ( ( pucSource[ 0 ] - ucCharA ) << 4 ) | + ucByte = ( uint8_t ) ( ( ( ( pucSource[ 0 ] - ucCharA ) & 0x0F ) << 4 ) | ( pucSource[ 1 ] - ucCharA ) ); /* Make sure there are no trailing spaces in the name. */ @@ -1208,7 +1217,11 @@ { /* BufferAllocation_1.c is used, the Network Buffers can contain at least * ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER. */ - configASSERT( uxSizeNeeded < ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ); + if( uxSizeNeeded > ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) + { + /* The buffer is too small to reply. Drop silently. */ + break; + } } pxNetworkBuffer->xDataLength = uxSizeNeeded; diff --git a/source/FreeRTOS_IP_Utils.c b/source/FreeRTOS_IP_Utils.c index 3754d4b0a1..bfe8aab27d 100644 --- a/source/FreeRTOS_IP_Utils.c +++ b/source/FreeRTOS_IP_Utils.c @@ -1694,6 +1694,81 @@ size_t FreeRTOS_min_size_t( size_t a, } /*-----------------------------------------------------------*/ +/** + * @brief Performs a safe addition of two 32-bit integers, preventing overflow and underflow. + * @param[in] a the first value. + * @param[in] b the second value. + * @return The result of a + b if no overflow/underflow occurs, or INT32_MAX/INT32_MIN if overflow/underflow would occur. + */ +int32_t FreeRTOS_add_int32( int32_t a, + int32_t b ) +{ + int32_t ret; + + if( ( a > 0 ) && ( b > ipINT32_MAX_VALUE - a ) ) + { + ret = ipINT32_MAX_VALUE; /* Positive overflow */ + } + else if( ( a < 0 ) && ( b < ipINT32_MIN_VALUE - a ) ) + { + ret = ipINT32_MIN_VALUE; /* Negative underflow */ + } + else + { + ret = a + b; + } + + return ret; +} +/*-----------------------------------------------------------*/ + +/** + * @brief Performs a safe multiplication of two 32-bit integers, preventing overflow and underflow. + * @param[in] a the first value. + * @param[in] b the second value. + * @return The result of a * b if no overflow occurs, or ipINT32_MAX_VALUE if an overflow would occur. + */ +int32_t FreeRTOS_multiply_int32( int32_t a, + int32_t b ) +{ + int32_t ret; + + /* Check for overflow/underflow */ + if( a > 0 ) + { + if( ( b > 0 ) && ( a > ipINT32_MAX_VALUE / b ) ) + { + ret = ipINT32_MAX_VALUE; /* Positive overflow */ + } + else if( ( b < 0 ) && ( b < ipINT32_MIN_VALUE / a ) ) + { + ret = ipINT32_MIN_VALUE; /* Negative underflow */ + } + else + { + ret = a * b; + } + } + else + { + if( ( b > 0 ) && ( a < ipINT32_MIN_VALUE / b ) ) + { + ret = ipINT32_MIN_VALUE; /* Negative underflow */ + } + else if( ( b < 0 ) && ( a < ipINT32_MAX_VALUE / b ) ) + { + ret = ipINT32_MAX_VALUE; /* Positive overflow */ + } + else + { + ret = a * b; + } + } + + return ret; +} +/*-----------------------------------------------------------*/ + /** * @brief Round-up a number to a multiple of 'd'. * @param[in] a the first value. diff --git a/source/FreeRTOS_TCP_Reception.c b/source/FreeRTOS_TCP_Reception.c index c86c847d1a..af5dcecbd6 100644 --- a/source/FreeRTOS_TCP_Reception.c +++ b/source/FreeRTOS_TCP_Reception.c @@ -99,7 +99,7 @@ size_t uxTCPHeaderOffset = ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket( pxNetworkBuffer ); /* MISRA Ref 11.3.1 [Misaligned access] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ /* coverity[misra_c_2012_rule_11_3_violation] */ const ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ uxTCPHeaderOffset ] ) ); @@ -237,7 +237,17 @@ /* Option is only valid in SYN phase. */ if( xHasSYNFlag != 0 ) { - pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ]; + /* From RFC7323 - section 2.3, we should limit the WSopt not larger than 14. */ + if( pucPtr[ 2 ] > tcpTCP_OPT_WSOPT_MAXIMUM_VALUE ) + { + FreeRTOS_debug_printf( ( "The WSopt(%u) from SYN packet is larger than maximum value.", pucPtr[ 2 ] ) ); + pxSocket->u.xTCP.ucPeerWinScaleFactor = tcpTCP_OPT_WSOPT_MAXIMUM_VALUE; + } + else + { + pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ]; + } + pxSocket->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED; } @@ -430,7 +440,7 @@ /* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ /* MISRA Ref 11.3.1 [Misaligned access] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ /* coverity[misra_c_2012_rule_11_3_violation] */ const ProtocolHeaders_t * pxProtocolHeaders = ( ( ProtocolHeaders_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ( size_t ) ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket( pxNetworkBuffer ) ] ) ); diff --git a/source/FreeRTOS_TCP_WIN.c b/source/FreeRTOS_TCP_WIN.c index 19c9ae6d8b..c883f40728 100644 --- a/source/FreeRTOS_TCP_WIN.c +++ b/source/FreeRTOS_TCP_WIN.c @@ -1901,18 +1901,33 @@ const TCPSegment_t * pxSegment ) { int32_t mS = ( int32_t ) ulTimerGetAge( &( pxSegment->xTransmitTimer ) ); + int32_t lSum = 0; + int32_t lWeight = 0; + int32_t lDivisor = 0; + + mS = mS < 0 ? ipINT32_MAX_VALUE : mS; if( pxWindow->lSRTT >= mS ) { /* RTT becomes smaller: adapt slowly. */ - pxWindow->lSRTT = ( ( winSRTT_DECREMENT_NEW * mS ) + ( winSRTT_DECREMENT_CURRENT * pxWindow->lSRTT ) ) / ( winSRTT_DECREMENT_NEW + winSRTT_DECREMENT_CURRENT ); + lWeight = winSRTT_DECREMENT_CURRENT; + lDivisor = winSRTT_DECREMENT_NEW + winSRTT_DECREMENT_CURRENT; + mS = FreeRTOS_multiply_int32( mS, + winSRTT_DECREMENT_NEW ); } else { /* RTT becomes larger: adapt quicker */ - pxWindow->lSRTT = ( ( winSRTT_INCREMENT_NEW * mS ) + ( winSRTT_INCREMENT_CURRENT * pxWindow->lSRTT ) ) / ( winSRTT_INCREMENT_NEW + winSRTT_INCREMENT_CURRENT ); + lWeight = winSRTT_INCREMENT_CURRENT; + lDivisor = winSRTT_INCREMENT_NEW + winSRTT_INCREMENT_CURRENT; + mS = FreeRTOS_multiply_int32( mS, + winSRTT_INCREMENT_NEW ); } + lSum = FreeRTOS_multiply_int32( pxWindow->lSRTT, lWeight ); + lSum = FreeRTOS_add_int32( lSum, mS ); + pxWindow->lSRTT = lSum / lDivisor; + /* Cap to the minimum of 50ms. */ if( pxWindow->lSRTT < winSRTT_CAP_mS ) { @@ -1946,7 +1961,7 @@ const ListItem_t * pxIterator; /* MISRA Ref 11.3.1 [Misaligned access] */ -/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ + /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-113 */ /* coverity[misra_c_2012_rule_11_3_violation] */ const ListItem_t * pxEnd = ( ( const ListItem_t * ) &( pxWindow->xTxSegments.xListEnd ) ); BaseType_t xDoUnlink; diff --git a/source/include/FreeRTOS_IP.h b/source/include/FreeRTOS_IP.h index 8e86ef4f63..9db3454158 100644 --- a/source/include/FreeRTOS_IP.h +++ b/source/include/FreeRTOS_IP.h @@ -60,6 +60,11 @@ #define ipSIZE_OF_UDP_HEADER 8U #define ipSIZE_OF_TCP_HEADER 20U +/* The maximum of int32 value. */ +#define ipINT32_MAX_VALUE ( ( int32_t ) 0x7FFFFFFF ) + +/* The minimum of int32 value. */ +#define ipINT32_MIN_VALUE ( ( int32_t ) 0x80000000 ) /* * Generate a randomized TCP Initial Sequence Number per RFC. @@ -270,6 +275,11 @@ uint32_t FreeRTOS_min_uint32( uint32_t a, size_t FreeRTOS_min_size_t( size_t a, size_t b ); +int32_t FreeRTOS_add_int32( int32_t a, + int32_t b ); +int32_t FreeRTOS_multiply_int32( int32_t a, + int32_t b ); + uint32_t FreeRTOS_round_up( uint32_t a, uint32_t d ); uint32_t FreeRTOS_round_down( uint32_t a, @@ -307,7 +317,7 @@ uint32_t FreeRTOS_round_down( uint32_t a, /* * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/01-FreeRTOS-plus-TCP-APIs */ /* FreeRTOS_IPInit_Multi() replaces the earlier FreeRTOS_IPInit(). It assumes diff --git a/source/include/FreeRTOS_Sockets.h b/source/include/FreeRTOS_Sockets.h index ec8bc3e6b5..9907fea47f 100644 --- a/source/include/FreeRTOS_Sockets.h +++ b/source/include/FreeRTOS_Sockets.h @@ -199,7 +199,7 @@ /** * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/01-FreeRTOS-plus-TCP-APIs */ /* Common Socket Attributes. */ diff --git a/source/include/FreeRTOS_TCP_IP.h b/source/include/FreeRTOS_TCP_IP.h index 3c478a2e86..e1a8c115df 100644 --- a/source/include/FreeRTOS_TCP_IP.h +++ b/source/include/FreeRTOS_TCP_IP.h @@ -96,25 +96,26 @@ typedef enum eTCP_STATE /* * A few values of the TCP options: */ -#define tcpTCP_OPT_END 0U /**< End of TCP options list. */ -#define tcpTCP_OPT_NOOP 1U /**< "No-operation" TCP option. */ -#define tcpTCP_OPT_MSS 2U /**< Maximum segment size TCP option. */ -#define tcpTCP_OPT_WSOPT 3U /**< TCP Window Scale Option (3-byte long). */ -#define tcpTCP_OPT_SACK_P 4U /**< Advertise that SACK is permitted. */ -#define tcpTCP_OPT_SACK_A 5U /**< SACK option with first/last. */ -#define tcpTCP_OPT_TIMESTAMP 8U /**< Time-stamp option. */ +#define tcpTCP_OPT_END 0U /**< End of TCP options list. */ +#define tcpTCP_OPT_NOOP 1U /**< "No-operation" TCP option. */ +#define tcpTCP_OPT_MSS 2U /**< Maximum segment size TCP option. */ +#define tcpTCP_OPT_WSOPT 3U /**< TCP Window Scale Option (3-byte long). */ +#define tcpTCP_OPT_SACK_P 4U /**< Advertise that SACK is permitted. */ +#define tcpTCP_OPT_SACK_A 5U /**< SACK option with first/last. */ +#define tcpTCP_OPT_TIMESTAMP 8U /**< Time-stamp option. */ -#define tcpTCP_OPT_MSS_LEN 4U /**< Length of TCP MSS option. */ -#define tcpTCP_OPT_WSOPT_LEN 3U /**< Length of TCP WSOPT option. */ +#define tcpTCP_OPT_MSS_LEN 4U /**< Length of TCP MSS option. */ +#define tcpTCP_OPT_WSOPT_LEN 3U /**< Length of TCP WSOPT option. */ +#define tcpTCP_OPT_WSOPT_MAXIMUM_VALUE ( 14U ) /**< Maximum value of TCP WSOPT option. */ -#define tcpTCP_OPT_TIMESTAMP_LEN 10 /**< fixed length of the time-stamp option. */ +#define tcpTCP_OPT_TIMESTAMP_LEN 10 /**< fixed length of the time-stamp option. */ /** @brief * Minimum segment length as outlined by RFC 791 section 3.1. * Minimum segment length ( 536 ) = Minimum MTU ( 576 ) - IP Header ( 20 ) - TCP Header ( 20 ). */ -#define tcpMINIMUM_SEGMENT_LENGTH 536U +#define tcpMINIMUM_SEGMENT_LENGTH 536U /** @brief * The macro tcpNOW_CONNECTED() is use to determine if the connection makes a diff --git a/source/include/IPTraceMacroDefaults.h b/source/include/IPTraceMacroDefaults.h index cb85afa7a4..c6c78cd77b 100644 --- a/source/include/IPTraceMacroDefaults.h +++ b/source/include/IPTraceMacroDefaults.h @@ -29,7 +29,7 @@ * @file IPTraceMacroDefaults.h * @brief This file provides default (empty) implementations for any IP trace * macros that are not defined by the user. See - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Trace.html + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/08-Trace-macros */ #ifndef IP_TRACE_MACRO_DEFAULTS_H diff --git a/source/portable/BufferManagement/BufferAllocation_1.c b/source/portable/BufferManagement/BufferAllocation_1.c index 9cbcad8cfe..787a3e8ad8 100644 --- a/source/portable/BufferManagement/BufferAllocation_1.c +++ b/source/portable/BufferManagement/BufferAllocation_1.c @@ -29,7 +29,7 @@ * * See the following web page for essential buffer allocation scheme usage and * configuration details: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/05-Buffer-management * ******************************************************************************/ @@ -237,11 +237,8 @@ NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedS BaseType_t xInvalid = pdFALSE; UBaseType_t uxCount; - /* The current implementation only has a single size memory block, so - * the requested size parameter is not used (yet). */ - ( void ) xRequestedSizeBytes; - - if( xNetworkBufferSemaphore != NULL ) + if( ( xNetworkBufferSemaphore != NULL ) && + ( xRequestedSizeBytes <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) ) { /* If there is a semaphore available, there is a network buffer * available. */ @@ -432,10 +429,18 @@ UBaseType_t uxGetNumberOfFreeNetworkBuffers( void ) NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes ) { - /* In BufferAllocation_1.c all network buffer are allocated with a - * maximum size of 'ipTOTAL_ETHERNET_FRAME_SIZE'.No need to resize the - * network buffer. */ - pxNetworkBuffer->xDataLength = xNewSizeBytes; + if( xNewSizeBytes <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) + { + /* In BufferAllocation_1.c all network buffer are allocated with a + * maximum size of 'ipTOTAL_ETHERNET_FRAME_SIZE'.No need to resize the + * network buffer. */ + pxNetworkBuffer->xDataLength = xNewSizeBytes; + } + else + { + pxNetworkBuffer = NULL; + } + return pxNetworkBuffer; } diff --git a/source/portable/BufferManagement/BufferAllocation_2.c b/source/portable/BufferManagement/BufferAllocation_2.c index 7c3f11283c..bb1dc034ff 100644 --- a/source/portable/BufferManagement/BufferAllocation_2.c +++ b/source/portable/BufferManagement/BufferAllocation_2.c @@ -31,7 +31,7 @@ * * See the following web page for essential buffer allocation scheme usage and * configuration details: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/05-Buffer-management * ******************************************************************************/ diff --git a/source/portable/Compiler/CompilerName/pack_struct_end.h b/source/portable/Compiler/CompilerName/pack_struct_end.h index 6abd64ef8b..259655c2b2 100644 --- a/source/portable/Compiler/CompilerName/pack_struct_end.h +++ b/source/portable/Compiler/CompilerName/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ ; /* FIX ME. Update for the compiler specifier needed at end of a struct declaration to pack the struct. */ diff --git a/source/portable/Compiler/CompilerName/pack_struct_start.h b/source/portable/Compiler/CompilerName/pack_struct_start.h index 3f144c5f60..49ff60eea8 100644 --- a/source/portable/Compiler/CompilerName/pack_struct_start.h +++ b/source/portable/Compiler/CompilerName/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ /* FIX ME. Update for the compiler specifier needed at the start of a struct declaration to pack the struct. */ diff --git a/source/portable/Compiler/GCC/pack_struct_end.h b/source/portable/Compiler/GCC/pack_struct_end.h index 1331692969..c9e312645f 100644 --- a/source/portable/Compiler/GCC/pack_struct_end.h +++ b/source/portable/Compiler/GCC/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ __attribute__( ( packed ) ); diff --git a/source/portable/Compiler/GCC/pack_struct_start.h b/source/portable/Compiler/GCC/pack_struct_start.h index 59ca8f40f3..1a319a66ed 100644 --- a/source/portable/Compiler/GCC/pack_struct_start.h +++ b/source/portable/Compiler/GCC/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/IAR/pack_struct_end.h b/source/portable/Compiler/IAR/pack_struct_end.h index 740f3e3be9..971529ceef 100644 --- a/source/portable/Compiler/IAR/pack_struct_end.h +++ b/source/portable/Compiler/IAR/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/IAR/pack_struct_start.h b/source/portable/Compiler/IAR/pack_struct_start.h index 24e43eb9c2..2751bde333 100644 --- a/source/portable/Compiler/IAR/pack_struct_start.h +++ b/source/portable/Compiler/IAR/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/Keil/pack_struct_end.h b/source/portable/Compiler/Keil/pack_struct_end.h index 1789634f8d..31480838b1 100644 --- a/source/portable/Compiler/Keil/pack_struct_end.h +++ b/source/portable/Compiler/Keil/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ ; diff --git a/source/portable/Compiler/Keil/pack_struct_start.h b/source/portable/Compiler/Keil/pack_struct_start.h index 16fdd905f9..4df49234c5 100644 --- a/source/portable/Compiler/Keil/pack_struct_start.h +++ b/source/portable/Compiler/Keil/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/MPLAB_XC/pack_struct_end.h b/source/portable/Compiler/MPLAB_XC/pack_struct_end.h index 8fb2056a60..4e77b14ef7 100644 --- a/source/portable/Compiler/MPLAB_XC/pack_struct_end.h +++ b/source/portable/Compiler/MPLAB_XC/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/MPLAB_XC/pack_struct_start.h b/source/portable/Compiler/MPLAB_XC/pack_struct_start.h index b5831a640e..cef1b9feff 100644 --- a/source/portable/Compiler/MPLAB_XC/pack_struct_start.h +++ b/source/portable/Compiler/MPLAB_XC/pack_struct_start.h @@ -28,6 +28,6 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/MSVC/pack_struct_end.h b/source/portable/Compiler/MSVC/pack_struct_end.h index e2ed5fee1e..a2c273faea 100644 --- a/source/portable/Compiler/MSVC/pack_struct_end.h +++ b/source/portable/Compiler/MSVC/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/MSVC/pack_struct_start.h b/source/portable/Compiler/MSVC/pack_struct_start.h index 9175b3c82d..8ff353309e 100644 --- a/source/portable/Compiler/MSVC/pack_struct_start.h +++ b/source/portable/Compiler/MSVC/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/Renesas/pack_struct_end.h b/source/portable/Compiler/Renesas/pack_struct_end.h index c8fbc60d68..c9625ee5f4 100644 --- a/source/portable/Compiler/Renesas/pack_struct_end.h +++ b/source/portable/Compiler/Renesas/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/Renesas/pack_struct_start.h b/source/portable/Compiler/Renesas/pack_struct_start.h index 1649b3105d..b7e63176f3 100644 --- a/source/portable/Compiler/Renesas/pack_struct_start.h +++ b/source/portable/Compiler/Renesas/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/Tasking/pack_struct_end.h b/source/portable/Compiler/Tasking/pack_struct_end.h index 9cce7beb6f..85799ac6d2 100644 --- a/source/portable/Compiler/Tasking/pack_struct_end.h +++ b/source/portable/Compiler/Tasking/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/Compiler/Tasking/pack_struct_start.h b/source/portable/Compiler/Tasking/pack_struct_start.h index 59ca8f40f3..1a319a66ed 100644 --- a/source/portable/Compiler/Tasking/pack_struct_start.h +++ b/source/portable/Compiler/Tasking/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/source/portable/NetworkInterface/M487/NetworkInterface.c b/source/portable/NetworkInterface/M487/NetworkInterface.c index 1005e90adf..4e880a97f4 100644 --- a/source/portable/NetworkInterface/M487/NetworkInterface.c +++ b/source/portable/NetworkInterface/M487/NetworkInterface.c @@ -73,7 +73,7 @@ static void prvEMACHandlerTask( void * pvParameters ); static void prvPhyTmrCallback( TimerHandle_t xTimer ); /* The size of each buffer when BufferAllocation_1 is used: - * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */ + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/05-Buffer-management */ #define niBUFFER_1_PACKET_SIZE 1536 #ifdef __ICCARM__ diff --git a/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c b/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c index 690231d6b3..70d2ae2c0c 100644 --- a/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c +++ b/source/portable/NetworkInterface/STM32Hxx/NetworkInterface.c @@ -1174,6 +1174,12 @@ static void prvEMACHandlerTask( void * pvParameters ) */ if( xSTM32H_GetPhyLinkStatus( pxMyInterface ) == pdFALSE ) { + #if ( ipconfigSUPPORT_NETWORK_DOWN_EVENT != 0 ) + { + FreeRTOS_NetworkDown( pxMyInterface ); + } + #endif /* ( ipconfigSUPPORT_NETWORK_DOWN_EVENT != 0 ) */ + /* Stop the DMA transfer. */ HAL_ETH_Stop_IT( &( xEthHandle ) ); /* Clear the Transmit buffers. */ diff --git a/source/portable/NetworkInterface/Zynq/NetworkInterface.c b/source/portable/NetworkInterface/Zynq/NetworkInterface.c index d7f2364d19..e403af9954 100644 --- a/source/portable/NetworkInterface/Zynq/NetworkInterface.c +++ b/source/portable/NetworkInterface/Zynq/NetworkInterface.c @@ -64,7 +64,7 @@ #define niBMSR_LINK_STATUS 0x0004uL /* The size of each buffer when BufferAllocation_1 is used: - * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */ + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/05-Buffer-management */ #define niBUFFER_1_PACKET_SIZE 1536 /* Naming and numbering of PHY registers. */ diff --git a/source/portable/NetworkInterface/board_family/NetworkInterface.c b/source/portable/NetworkInterface/board_family/NetworkInterface.c index 76c4a4842a..0f4d744c3e 100644 --- a/source/portable/NetworkInterface/board_family/NetworkInterface.c +++ b/source/portable/NetworkInterface/board_family/NetworkInterface.c @@ -31,7 +31,7 @@ * concrete implementations of the functions in this file. * * See the following URL for an explanation of this file and its functions: -* https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/03-Embedded_Ethernet_Porting * *****************************************************************************/ diff --git a/source/portable/NetworkInterface/board_family/ReadMe.txt b/source/portable/NetworkInterface/board_family/ReadMe.txt index 782e429355..352670ab5c 100644 --- a/source/portable/NetworkInterface/board_family/ReadMe.txt +++ b/source/portable/NetworkInterface/board_family/ReadMe.txt @@ -2,4 +2,4 @@ Update NetworkInterface.c and include other files needed by FreeRTOS+TCP here. Note: The NetworkInterface.c file in this directory is Not! to be used as is. The purpose of the file is to provide a template for writing a network interface. Each network interface will have to provide concrete implementations of the functions in NetworkInterface.c. -See the following URL for an explanation of the file and its functions: https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Porting.html \ No newline at end of file +See the following URL for an explanation of the file and its functions: https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/03-Embedded_Ethernet_Porting \ No newline at end of file diff --git a/source/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c b/source/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c index 7d7737a5c3..a2fbb444a0 100644 --- a/source/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c +++ b/source/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c @@ -29,7 +29,7 @@ * * See the following web page for essential buffer allocation scheme usage and * configuration details: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/05-Buffer-management * ******************************************************************************/ diff --git a/source/portable/NetworkInterface/xilinx_ultrascale/NetworkInterface.c b/source/portable/NetworkInterface/xilinx_ultrascale/NetworkInterface.c index 189d3d6c05..e4c5c841b2 100644 --- a/source/portable/NetworkInterface/xilinx_ultrascale/NetworkInterface.c +++ b/source/portable/NetworkInterface/xilinx_ultrascale/NetworkInterface.c @@ -68,7 +68,7 @@ #endif /* The size of each buffer when BufferAllocation_1 is used: - * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */ + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/05-Buffer-management */ #if ( USE_JUMBO_FRAMES == 1 ) #define niBUFFER_1_PACKET_SIZE 10240 #else diff --git a/test/Coverity/ConfigFiles/FreeRTOSIPConfig.h b/test/Coverity/ConfigFiles/FreeRTOSIPConfig.h index ad4095b30f..6d806e9fc8 100644 --- a/test/Coverity/ConfigFiles/FreeRTOSIPConfig.h +++ b/test/Coverity/ConfigFiles/FreeRTOSIPConfig.h @@ -103,7 +103,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/Coverity/ConfigFiles/pack_struct_end.h b/test/Coverity/ConfigFiles/pack_struct_end.h index 038d091f11..55570aa872 100644 --- a/test/Coverity/ConfigFiles/pack_struct_end.h +++ b/test/Coverity/ConfigFiles/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/test/Coverity/ConfigFiles/pack_struct_start.h b/test/Coverity/ConfigFiles/pack_struct_start.h index 59ca8f40f3..1a319a66ed 100644 --- a/test/Coverity/ConfigFiles/pack_struct_start.h +++ b/test/Coverity/ConfigFiles/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/test/Coverity/README.md b/test/Coverity/README.md index db4579b585..f75869c560 100644 --- a/test/Coverity/README.md +++ b/test/Coverity/README.md @@ -13,7 +13,7 @@ see the [MISRA.md](https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA ## Getting Started ### Prerequisites -You can run this on a platform supported by Coverity. The list and other details can be found [here](https://sig-docs.synopsys.com/polaris/topics/c_coverity-compatible-platforms.html). +You can run this on a platform supported by Coverity. The list and other details can be found [here](https://documentation.blackduck.com/bundle/coverity-docs/page/deploy-install-guide/topics/supported_platforms_for_coverity_analysis.html). To compile and run the Coverity target successfully, you must have the following: 1. CMake version > 3.13.0 (You can check whether you have this by typing `cmake --version`) diff --git a/test/build-combination/AllDisable/FreeRTOSIPConfig.h b/test/build-combination/AllDisable/FreeRTOSIPConfig.h index a7f56690f4..a5eab85e44 100644 --- a/test/build-combination/AllDisable/FreeRTOSIPConfig.h +++ b/test/build-combination/AllDisable/FreeRTOSIPConfig.h @@ -99,7 +99,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 0 diff --git a/test/build-combination/AllEnable/FreeRTOSIPConfig.h b/test/build-combination/AllEnable/FreeRTOSIPConfig.h index a14cde04f9..9755daec61 100644 --- a/test/build-combination/AllEnable/FreeRTOSIPConfig.h +++ b/test/build-combination/AllEnable/FreeRTOSIPConfig.h @@ -130,7 +130,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/build-combination/Enable_IPv4/FreeRTOSIPConfig.h b/test/build-combination/Enable_IPv4/FreeRTOSIPConfig.h index bf87a07c49..c6fe0c58d8 100644 --- a/test/build-combination/Enable_IPv4/FreeRTOSIPConfig.h +++ b/test/build-combination/Enable_IPv4/FreeRTOSIPConfig.h @@ -133,7 +133,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/build-combination/Enable_IPv4_IPv6/FreeRTOSIPConfig.h b/test/build-combination/Enable_IPv4_IPv6/FreeRTOSIPConfig.h index 461c49e04b..495c556fed 100644 --- a/test/build-combination/Enable_IPv4_IPv6/FreeRTOSIPConfig.h +++ b/test/build-combination/Enable_IPv4_IPv6/FreeRTOSIPConfig.h @@ -133,7 +133,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/build-combination/Enable_IPv4_TCP/FreeRTOSIPConfig.h b/test/build-combination/Enable_IPv4_TCP/FreeRTOSIPConfig.h index e412e550f5..b5abac7c37 100644 --- a/test/build-combination/Enable_IPv4_TCP/FreeRTOSIPConfig.h +++ b/test/build-combination/Enable_IPv4_TCP/FreeRTOSIPConfig.h @@ -133,7 +133,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/build-combination/Enable_IPv6/FreeRTOSIPConfig.h b/test/build-combination/Enable_IPv6/FreeRTOSIPConfig.h index 79497c4624..8d5ee043fd 100644 --- a/test/build-combination/Enable_IPv6/FreeRTOSIPConfig.h +++ b/test/build-combination/Enable_IPv6/FreeRTOSIPConfig.h @@ -133,7 +133,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/build-combination/Enable_IPv6_TCP/FreeRTOSIPConfig.h b/test/build-combination/Enable_IPv6_TCP/FreeRTOSIPConfig.h index 22031a32fc..88df29d996 100644 --- a/test/build-combination/Enable_IPv6_TCP/FreeRTOSIPConfig.h +++ b/test/build-combination/Enable_IPv6_TCP/FreeRTOSIPConfig.h @@ -133,7 +133,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/build-combination/Header_Self_Contain/FreeRTOSIPConfig.h b/test/build-combination/Header_Self_Contain/FreeRTOSIPConfig.h index 2ef78a36c0..622fa1e7c6 100644 --- a/test/build-combination/Header_Self_Contain/FreeRTOSIPConfig.h +++ b/test/build-combination/Header_Self_Contain/FreeRTOSIPConfig.h @@ -129,7 +129,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/cbmc/patches/FreeRTOSIPConfig.h b/test/cbmc/patches/FreeRTOSIPConfig.h index ab571ac6da..d17a6e7391 100644 --- a/test/cbmc/patches/FreeRTOSIPConfig.h +++ b/test/cbmc/patches/FreeRTOSIPConfig.h @@ -96,7 +96,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/cbmc/proofs/ARP/ARPAgeCache/ARPAgeCache_harness.c b/test/cbmc/proofs/ARP/ARPAgeCache/ARPAgeCache_harness.c index 5a5b3e7c2a..509cacb7ba 100644 --- a/test/cbmc/proofs/ARP/ARPAgeCache/ARPAgeCache_harness.c +++ b/test/cbmc/proofs/ARP/ARPAgeCache/ARPAgeCache_harness.c @@ -33,6 +33,12 @@ BaseType_t NetworkInterfaceOutputFunction_Stub( struct xNetworkInterface * pxDes return 0; } + +void FreeRTOS_OutputAdvertiseIPv6( NetworkEndPoint_t * pxEndPoint ) +{ + __CPROVER_assert( pxEndPoint != NULL, "The Endpoint cannot be NULL." ); +} + void harness() { /* diff --git a/test/cbmc/proofs/ARP/ARPAgeCache/Makefile.json b/test/cbmc/proofs/ARP/ARPAgeCache/Makefile.json index 24de2ff3c0..b122ddc7dc 100644 --- a/test/cbmc/proofs/ARP/ARPAgeCache/Makefile.json +++ b/test/cbmc/proofs/ARP/ARPAgeCache/Makefile.json @@ -15,6 +15,9 @@ "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto" ], "DEF": diff --git a/test/cbmc/proofs/ARP/ARPGetCacheEntry/ARPGetCacheEntry_harness.c b/test/cbmc/proofs/ARP/ARPGetCacheEntry/ARPGetCacheEntry_harness.c index 9b1e4b227c..51bad65b7e 100644 --- a/test/cbmc/proofs/ARP/ARPGetCacheEntry/ARPGetCacheEntry_harness.c +++ b/test/cbmc/proofs/ARP/ARPGetCacheEntry/ARPGetCacheEntry_harness.c @@ -12,6 +12,7 @@ void harness() { uint32_t ulIPAddress; MACAddress_t xMACAddress; + struct xNetworkEndPoint * pxEndPoint = NULL; /* * For this proof, its assumed that the endpoints and interfaces are correctly @@ -38,13 +39,5 @@ void harness() pxNetworkEndPoints->pxNext = NULL; } - NetworkInterface_t ** ppxInterface = ( NetworkInterface_t ** ) malloc( sizeof( NetworkInterface_t * ) ); - - if( ppxInterface ) - { - *ppxInterface = ( NetworkInterface_t * ) malloc( sizeof( NetworkInterface_t ) ); - __CPROVER_assume( *ppxInterface != NULL ); - } - - eARPGetCacheEntry( &ulIPAddress, &xMACAddress, ppxInterface ); + eARPGetCacheEntry( &ulIPAddress, &xMACAddress, &pxEndPoint ); } diff --git a/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json b/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json index aa4d602966..3301afb404 100644 --- a/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json +++ b/test/cbmc/proofs/ARP/ARPGetCacheEntry/Configurations.json @@ -14,6 +14,8 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IPv4.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IPv4_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto" ], "DEF": diff --git a/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c b/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c index 539f02d180..7be8045595 100644 --- a/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c +++ b/test/cbmc/proofs/ARP/ARPProcessPacket/ARPProcessPacket_harness.c @@ -1,5 +1,3 @@ -#include "cbmc.h" - /* FreeRTOS includes. */ #include "FreeRTOS.h" #include "queue.h" @@ -10,8 +8,37 @@ #include "FreeRTOS_ARP.h" #include "FreeRTOS_Routing.h" +/* CBMC includes. */ +#include "cbmc.h" + /* This pointer is maintained by the IP-task. Defined in FreeRTOS_IP.c */ extern NetworkBufferDescriptor_t * pxARPWaitingNetworkBuffer; +NetworkEndPoint_t * pxNetworkEndPoint_Temp; + +/* Stub FreeRTOS_FindEndPointOnNetMask_IPv6 as its not relevant to the + * correctness of the proof */ +NetworkEndPoint_t * FreeRTOS_FindEndPointOnNetMask_IPv6( const IPv6_Address_t * pxIPv6Address ) +{ + __CPROVER_assert( pxIPv6Address != NULL, "Precondition: pxIPv6Address != NULL" ); + + /* Assume at least one end-point is available */ + return pxNetworkEndPoint_Temp; +} + +/* Stub FreeRTOS_FindEndPointOnNetMask_IPv6 as its not relevant to the + * correctness of the proof */ +NetworkEndPoint_t * FreeRTOS_FindEndPointOnNetMask( uint32_t ulIPAddress, + uint32_t ulWhere ) +{ + /* Assume at least one end-point is available */ + return pxNetworkEndPoint_Temp; +} + +/* Get rid of configASSERT in FreeRTOS_TCP_IP.c */ +BaseType_t xIsCallingFromIPTask( void ) +{ + return pdTRUE; +} /* This is an output function and need not be tested with this proof. */ void FreeRTOS_OutputARPRequest_Multi( NetworkEndPoint_t * pxEndPoint, @@ -36,9 +63,19 @@ eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress, void harness() { - NetworkBufferDescriptor_t xLocalBuffer; + NetworkBufferDescriptor_t * pxLocalBuffer; + NetworkBufferDescriptor_t * pxNetworkBuffer2; + TickType_t xBlockTimeTicks; uint16_t usEthernetBufferSize; + /* + * The assumption made here is that the buffer pointed by pucEthernetBuffer + * is at least allocated to sizeof(ARPPacket_t) size but eventually an even larger buffer. + * This is not checked inside eARPProcessPacket. + */ + uint8_t ucBUFFER_SIZE; + + /* Non deterministically determine whether the pxARPWaitingNetworkBuffer will * point to some valid data or will it be NULL. */ if( nondet_bool() ) @@ -47,48 +84,34 @@ void harness() * checked in the function as the pointer is stored by the IP-task itself * and therefore it will always be of the required size. */ __CPROVER_assume( usEthernetBufferSize >= sizeof( IPPacket_t ) ); - - /* Add matching data length to the network buffer descriptor. */ - __CPROVER_assume( xLocalBuffer.xDataLength == usEthernetBufferSize ); - - xLocalBuffer.pucEthernetBuffer = malloc( usEthernetBufferSize ); + pxLocalBuffer = pxGetNetworkBufferWithDescriptor( usEthernetBufferSize, xBlockTimeTicks ); /* Since this pointer is maintained by the IP-task, either the pointer - * pxARPWaitingNetworkBuffer will be NULL or xLocalBuffer.pucEthernetBuffer + * pxARPWaitingNetworkBuffer will be NULL or pxLocalBuffer->pucEthernetBuffer * will be non-NULL. */ - __CPROVER_assume( xLocalBuffer.pucEthernetBuffer != NULL ); + __CPROVER_assume( pxLocalBuffer != NULL ); + __CPROVER_assume( pxLocalBuffer->pucEthernetBuffer != NULL ); + __CPROVER_assume( pxLocalBuffer->xDataLength == usEthernetBufferSize ); - pxARPWaitingNetworkBuffer = &xLocalBuffer; + pxARPWaitingNetworkBuffer = pxLocalBuffer; } else { pxARPWaitingNetworkBuffer = NULL; } - /* - * The assumption made here is that the buffer pointed by pucEthernetBuffer - * is at least allocated to sizeof(ARPPacket_t) size but eventually an even larger buffer. - * This is not checked inside eARPProcessPacket. - */ - uint8_t ucBUFFER_SIZE; - - void * xBuffer = malloc( ucBUFFER_SIZE + sizeof( ARPPacket_t ) ); - - __CPROVER_assume( xBuffer != NULL ); - - NetworkBufferDescriptor_t xNetworkBuffer2; - - xNetworkBuffer2.pucEthernetBuffer = xBuffer; - xNetworkBuffer2.xDataLength = ucBUFFER_SIZE + sizeof( ARPPacket_t ); + pxNetworkBuffer2 = pxGetNetworkBufferWithDescriptor( ucBUFFER_SIZE + sizeof( ARPPacket_t ), xBlockTimeTicks ); + __CPROVER_assume( pxNetworkBuffer2 != NULL ); + __CPROVER_assume( pxNetworkBuffer2->pucEthernetBuffer != NULL ); /* * This proof assumes one end point is present. */ - xNetworkBuffer2.pxEndPoint = ( NetworkEndPoint_t * ) malloc( sizeof( NetworkEndPoint_t ) ); - __CPROVER_assume( xNetworkBuffer2.pxEndPoint != NULL ); - xNetworkBuffer2.pxEndPoint->pxNext = NULL; + pxNetworkBuffer2->pxEndPoint = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); + __CPROVER_assume( pxNetworkBuffer2->pxEndPoint != NULL ); + pxNetworkBuffer2->pxEndPoint->pxNext = NULL; /* eARPProcessPacket will be called in the source code only after checking if - * xNetworkBuffer2.pucEthernetBuffer is not NULL, hence, __CPROVER_assume( xBuffer != NULL ); */ - eARPProcessPacket( &xNetworkBuffer2 ); + * pxNetworkBuffer2->pucEthernetBuffer is not NULL, hence, __CPROVER_assume( xBuffer != NULL ); */ + eARPProcessPacket( pxNetworkBuffer2 ); } diff --git a/test/cbmc/proofs/ARP/ARPProcessPacket/Makefile.json b/test/cbmc/proofs/ARP/ARPProcessPacket/Makefile.json index 00079ded19..003611ae97 100644 --- a/test/cbmc/proofs/ARP/ARPProcessPacket/Makefile.json +++ b/test/cbmc/proofs/ARP/ARPProcessPacket/Makefile.json @@ -11,6 +11,9 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto" ] } diff --git a/test/cbmc/proofs/ARP/ARPSendGratuitous/Makefile.json b/test/cbmc/proofs/ARP/ARPSendGratuitous/Makefile.json index f069f59597..044a2b2c2d 100644 --- a/test/cbmc/proofs/ARP/ARPSendGratuitous/Makefile.json +++ b/test/cbmc/proofs/ARP/ARPSendGratuitous/Makefile.json @@ -10,7 +10,9 @@ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", - "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", + "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto" ], "DEF": [ diff --git a/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/Configurations.json b/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/Configurations.json index 62bb3e0523..5e2c516c39 100644 --- a/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/Configurations.json +++ b/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/Configurations.json @@ -37,7 +37,9 @@ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto" ], #That is the minimal required size for an ARPPacket_t plus offset in the buffer. "MINIMUM_PACKET_BYTES": 50, diff --git a/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/OutputARPRequest_harness.c b/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/OutputARPRequest_harness.c index 9337fb4f74..b5b45cf674 100644 --- a/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/OutputARPRequest_harness.c +++ b/test/cbmc/proofs/ARP/ARP_FreeRTOS_OutputARPRequest/OutputARPRequest_harness.c @@ -35,6 +35,8 @@ #include "FreeRTOS_IP_Private.h" #include "FreeRTOS_ARP.h" +/* CBMC includes. */ +#include "cbmc.h" ARPPacket_t xARPPacket; NetworkBufferDescriptor_t xNetworkBuffer; @@ -56,15 +58,15 @@ NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedS { #ifdef CBMC_PROOF_ASSUMPTION_HOLDS #if ( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 ) - xNetworkBuffer.pucEthernetBuffer = malloc( ipconfigETHERNET_MINIMUM_PACKET_BYTES ); + xNetworkBuffer.pucEthernetBuffer = safeMalloc( ipconfigETHERNET_MINIMUM_PACKET_BYTES ); #else - xNetworkBuffer.pucEthernetBuffer = malloc( xRequestedSizeBytes ); + xNetworkBuffer.pucEthernetBuffer = safeMalloc( xRequestedSizeBytes ); #endif #else uint32_t malloc_size; __CPROVER_assert( !__CPROVER_overflow_mult( 2, xRequestedSizeBytes ) ); __CPROVER_assume( malloc_size > 0 && malloc_size < 2 * xRequestedSizeBytes ); - xNetworkBuffer.pucEthernetBuffer = malloc( malloc_size ); + xNetworkBuffer.pucEthernetBuffer = safeMalloc( malloc_size ); #endif __CPROVER_assume( xNetworkBuffer.pucEthernetBuffer != NULL ); @@ -72,6 +74,21 @@ NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedS return &xNetworkBuffer; } +/* STUB! + * In this function, it only allocates network buffer by pxGetNetworkBufferWithDescriptor + * stub function above here. In this case, we should just free the allocated pucEthernetBuffer. + */ +void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, + "Precondition: pxNetworkBuffer != NULL" ); + + if( pxNetworkBuffer->pucEthernetBuffer != NULL ) + { + free( pxNetworkBuffer->pucEthernetBuffer ); + } +} + BaseType_t NetworkInterfaceOutputFunction_Stub( struct xNetworkInterface * pxDescriptor, NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend ) @@ -81,6 +98,14 @@ BaseType_t NetworkInterfaceOutputFunction_Stub( struct xNetworkInterface * pxDes __CPROVER_assert( pxNetworkBuffer->pucEthernetBuffer != NULL, "The ethernet buffer cannot be NULL." ); } +BaseType_t xIsCallingFromIPTask( void ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdFALSE || xReturn == pdTRUE ); + + return xReturn; +} void harness() { @@ -92,16 +117,16 @@ void harness() * Assumes one endpoint and interface is present. */ - pxNetworkEndPoints = ( NetworkEndPoint_t * ) malloc( sizeof( NetworkEndPoint_t ) ); + pxNetworkEndPoints = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); __CPROVER_assume( pxNetworkEndPoints != NULL ); /* Interface init. */ - pxNetworkEndPoints->pxNetworkInterface = ( NetworkInterface_t * ) malloc( sizeof( NetworkInterface_t ) ); + pxNetworkEndPoints->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); __CPROVER_assume( pxNetworkEndPoints->pxNetworkInterface != NULL ); if( nondet_bool() ) { - pxNetworkEndPoints->pxNext = ( NetworkEndPoint_t * ) malloc( sizeof( NetworkEndPoint_t ) ); + pxNetworkEndPoints->pxNext = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); __CPROVER_assume( pxNetworkEndPoints->pxNext != NULL ); pxNetworkEndPoints->pxNext->pxNext = NULL; pxNetworkEndPoints->pxNext->pxNetworkInterface = pxNetworkEndPoints->pxNetworkInterface; diff --git a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/Configurations.json b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/Configurations.json index e243382c31..ff5898c18c 100644 --- a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/Configurations.json +++ b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/Configurations.json @@ -14,7 +14,9 @@ "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", "$(FREERTOS_PLUS_TCP)/source/portable/BufferManagement/BufferAllocation_1.goto", "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto", - "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/queue.goto" + "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/queue.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/proofs/CBMCStubLibrary/tasksStubs.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto" ], "DEF": [ diff --git a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/OutputARPRequest_harness.c b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/OutputARPRequest_harness.c index 492d97683a..24762ed1cd 100644 --- a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/OutputARPRequest_harness.c +++ b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc1/OutputARPRequest_harness.c @@ -75,6 +75,14 @@ BaseType_t NetworkInterfaceOutputFunction_Stub( struct xNetworkInterface * pxDes } } +BaseType_t xIsCallingFromIPTask( void ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdFALSE || xReturn == pdTRUE ); + + return xReturn; +} void harness() { @@ -92,6 +100,7 @@ void harness() /* Interface init. */ pxNetworkEndPoints->pxNetworkInterface = ( NetworkInterface_t * ) malloc( sizeof( NetworkInterface_t ) ); + __CPROVER_assume( pxNetworkEndPoints->pxNetworkInterface != NULL ); pxNetworkEndPoints->pxNetworkInterface->pxNext = NULL; pxNetworkEndPoints->pxNetworkInterface->pfOutput = NetworkInterfaceOutputFunction_Stub; diff --git a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/Configurations.json b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/Configurations.json index 5b2cdd30db..d37f17720e 100644 --- a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/Configurations.json +++ b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/Configurations.json @@ -14,7 +14,9 @@ "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", "$(FREERTOS_PLUS_TCP)/source/portable/BufferManagement/BufferAllocation_2.goto", "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto", - "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/queue.goto" + "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/queue.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/proofs/CBMCStubLibrary/tasksStubs.goto" ], "DEF": [ diff --git a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/OutputARPRequest_harness.c b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/OutputARPRequest_harness.c index 4d84934494..af3abf26e9 100644 --- a/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/OutputARPRequest_harness.c +++ b/test/cbmc/proofs/ARP/ARP_OutputARPRequest_buffer_alloc2/OutputARPRequest_harness.c @@ -55,6 +55,15 @@ BaseType_t NetworkInterfaceOutputFunction_Stub( struct xNetworkInterface * pxDes } } +BaseType_t xIsCallingFromIPTask( void ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdFALSE || xReturn == pdTRUE ); + + return xReturn; +} + void harness() { BaseType_t xRes = xNetworkBuffersInitialise(); @@ -71,6 +80,7 @@ void harness() /* Interface init. */ pxNetworkEndPoints->pxNetworkInterface = ( NetworkInterface_t * ) malloc( sizeof( NetworkInterface_t ) ); + __CPROVER_assume( pxNetworkEndPoints->pxNetworkInterface != NULL ); pxNetworkEndPoints->pxNetworkInterface->pxNext = NULL; pxNetworkEndPoints->pxNetworkInterface->pfOutput = NetworkInterfaceOutputFunction_Stub; diff --git a/test/cbmc/proofs/CheckOptionsInner/CheckOptionsInner_harness.c b/test/cbmc/proofs/CheckOptionsInner/CheckOptionsInner_harness.c index e4a08e2eee..3da849aaf4 100644 --- a/test/cbmc/proofs/CheckOptionsInner/CheckOptionsInner_harness.c +++ b/test/cbmc/proofs/CheckOptionsInner/CheckOptionsInner_harness.c @@ -32,8 +32,6 @@ void __CPROVER_file_local_FreeRTOS_TCP_Reception_c_prvReadSackOption( const uint * Proof of prvReadSackOption function contract ****************************************************************/ - - void harness() { /* pucPtr points into a buffer */ @@ -87,7 +85,7 @@ void harness() /* Preconditions */ /* CBMC model of pointers limits the size of the buffer */ - __CPROVER_assume( buffer_size < CBMC_MAX_OBJECT_SIZE ); + __CPROVER_assume( buffer_size < ipconfigNETWORK_MTU ); /* Both preconditions are required to avoid integer overflow in the */ /* pointer offset of the pointer pucPtr + uxIndex + 8 */ @@ -97,6 +95,8 @@ void harness() /* Assuming quite a bit more about the initialization of pxSocket */ __CPROVER_assume( pucPtr != NULL ); __CPROVER_assume( pxSocket != NULL ); + /* lSRTT is guaranteed to be always greater than or equal to minimum value. */ + __CPROVER_assume( pxSocket->u.xTCP.xTCPWindow.lSRTT >= ipconfigTCP_SRTT_MINIMUM_VALUE_MS ); __CPROVER_file_local_FreeRTOS_TCP_Reception_c_prvReadSackOption( pucPtr, uxIndex, pxSocket ); diff --git a/test/cbmc/proofs/CheckOptionsInner/Makefile.json b/test/cbmc/proofs/CheckOptionsInner/Makefile.json index a902bcc944..522ca4ccad 100644 --- a/test/cbmc/proofs/CheckOptionsInner/Makefile.json +++ b/test/cbmc/proofs/CheckOptionsInner/Makefile.json @@ -12,6 +12,7 @@ "OBJS": [ "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Reception.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_WIN.goto", @@ -21,6 +22,7 @@ ], "DEF": [ - "ipconfigUSE_TCP=1" + "ipconfigUSE_TCP=1", + "ipconfigNETWORK_MTU=586" ] } diff --git a/test/cbmc/proofs/CheckOptionsOuter/CheckOptionsOuter_harness.c b/test/cbmc/proofs/CheckOptionsOuter/CheckOptionsOuter_harness.c index 3d58d0dd1d..867305d930 100644 --- a/test/cbmc/proofs/CheckOptionsOuter/CheckOptionsOuter_harness.c +++ b/test/cbmc/proofs/CheckOptionsOuter/CheckOptionsOuter_harness.c @@ -81,7 +81,7 @@ void harness() ****************************************************************/ /* CBMC model of pointers limits the size of the buffer */ - __CPROVER_assume( buffer_size < CBMC_MAX_OBJECT_SIZE ); + __CPROVER_assume( buffer_size < ipconfigNETWORK_MTU ); /* Preconditions */ __CPROVER_assume( 8 <= buffer_size ); /* ulFirst and ulLast */ diff --git a/test/cbmc/proofs/CheckOptionsOuter/Makefile.json b/test/cbmc/proofs/CheckOptionsOuter/Makefile.json index d97be23e62..898d1ea5ba 100644 --- a/test/cbmc/proofs/CheckOptionsOuter/Makefile.json +++ b/test/cbmc/proofs/CheckOptionsOuter/Makefile.json @@ -12,6 +12,7 @@ "OBJS": [ "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Reception.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_WIN.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Stream_Buffer.goto", @@ -20,5 +21,6 @@ ], "DEF": [ + "ipconfigNETWORK_MTU=586" ] } diff --git a/test/cbmc/proofs/DHCP/DHCPProcess/DHCPProcess_harness.c b/test/cbmc/proofs/DHCP/DHCPProcess/DHCPProcess_harness.c index 10c6aacf83..6ba76d4be0 100644 --- a/test/cbmc/proofs/DHCP/DHCPProcess/DHCPProcess_harness.c +++ b/test/cbmc/proofs/DHCP/DHCPProcess/DHCPProcess_harness.c @@ -49,6 +49,7 @@ /* Static members defined in FreeRTOS_DHCP.c */ extern DHCPData_t xDHCPData; extern Socket_t xDHCPv4Socket; +extern BaseType_t xDHCPSocketUserCount; void prvCreateDHCPSocket( NetworkEndPoint_t * pxEndPoint ); uint32_t uxSocketCloseCnt = 0; @@ -166,6 +167,13 @@ int32_t FreeRTOS_recvfrom( Socket_t xSocket, return retVal; } +void * vSocketClose( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL." ); + + return NULL; +} + /**************************************************************** * The proof of vDHCPProcess ****************************************************************/ @@ -175,6 +183,9 @@ void harness() BaseType_t xReset; eDHCPState_t eExpectedState; + /* The only possibility of making xDHCPSocketUserCount overflow is having more than BaseType_t endpoints, which is assumed not possible here. */ + __CPROVER_assume( xDHCPSocketUserCount >= 0 && xDHCPSocketUserCount <= ENDPOINT_DNS_ADDRESS_COUNT ); + pxNetworkEndPoints = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); __CPROVER_assume( pxNetworkEndPoints != NULL ); diff --git a/test/cbmc/proofs/DHCP/DHCPProcess/Makefile.json b/test/cbmc/proofs/DHCP/DHCPProcess/Makefile.json index 99e79d3b2e..8de985a953 100644 --- a/test/cbmc/proofs/DHCP/DHCPProcess/Makefile.json +++ b/test/cbmc/proofs/DHCP/DHCPProcess/Makefile.json @@ -24,7 +24,8 @@ "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto" ], "DEF": [ @@ -32,6 +33,7 @@ "BUFFER_SIZE={BUFFER_SIZE}", "ipconfigDHCP_REGISTER_HOSTNAME=1", "CBMC_REQUIRE_NETWORKBUFFER_ETHERNETBUFFER_NONNULL=1", - "CBMC_GETNETWORKBUFFER_FAILURE_BOUND={FAILURE_BOUND}" + "CBMC_GETNETWORKBUFFER_FAILURE_BOUND={FAILURE_BOUND}", + "ENDPOINT_DNS_ADDRESS_COUNT={ENDPOINT_DNS_ADDRESS_COUNT}" ] } diff --git a/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/DHCPProcessEndPoint_harness.c b/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/DHCPProcessEndPoint_harness.c index db482595cd..74891fa02a 100644 --- a/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/DHCPProcessEndPoint_harness.c +++ b/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/DHCPProcessEndPoint_harness.c @@ -51,6 +51,7 @@ /* Static members defined in FreeRTOS_DHCP.c */ extern DHCPData_t xDHCPData; extern Socket_t xDHCPv4Socket; +extern BaseType_t xDHCPSocketUserCount; void prvCreateDHCPSocket( NetworkEndPoint_t * pxEndPoint ); /* Static member defined in freertos_api.c */ @@ -145,6 +146,35 @@ Socket_t FreeRTOS_socket( BaseType_t xDomain, return ensure_FreeRTOS_Socket_t_is_allocated(); } +void vApplicationIPNetworkEventHook_Multi( eIPCallbackEvent_t eNetworkEvent, + struct xNetworkEndPoint * pxEndPoint ) +{ + __CPROVER_assert( eNetworkEvent == eNetworkUp || eNetworkEvent == eNetworkDown, "Network event is not correct" ); + __CPROVER_assert( pxEndPoint != NULL, "Endpoint cannot be NULL" ); +} + +BaseType_t xIsCallingFromIPTask( void ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdFALSE || xReturn == pdTRUE ); + + return xReturn; +} + +void * vSocketClose( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL" ); + + return NULL; +} + +void vManageSolicitedNodeAddress( const struct xNetworkEndPoint * pxEndPoint, + BaseType_t xNetworkGoingUp ) +{ + __CPROVER_assert( pxEndPoint != NULL, "Endpoint cannot be NULL" ); + __CPROVER_assert( pxEndPoint->pxNetworkInterface != NULL, "The network interface cannot be NULL" ); +} /**************************************************************** * The proof of vDHCPProcess @@ -155,6 +185,9 @@ void harness() BaseType_t xReset; BaseType_t xDoCheck; + /* The only possibility of making xDHCPSocketUserCount overflow is having more than BaseType_t endpoints, which is assumed not possible here. */ + __CPROVER_assume( xDHCPSocketUserCount >= 0 && xDHCPSocketUserCount <= ENDPOINT_DNS_ADDRESS_COUNT ); + pxNetworkEndPoints = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); __CPROVER_assume( pxNetworkEndPoints != NULL ); @@ -178,6 +211,7 @@ void harness() __CPROVER_assume( pxNetworkEndPoint_Temp != NULL ); pxNetworkEndPoint_Temp->pxNext = NULL; pxNetworkEndPoint_Temp->xDHCPData.xDHCPSocket = NULL; + pxNetworkEndPoint_Temp->pxNetworkInterface = pxNetworkEndPoints->pxNetworkInterface; /**************************************************************** * Initialize the counter used to bound the number of times diff --git a/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/Makefile.json b/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/Makefile.json index ed74976135..75426470db 100644 --- a/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/Makefile.json +++ b/test/cbmc/proofs/DHCP/DHCPProcessEndPoint/Makefile.json @@ -23,8 +23,10 @@ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ARP.goto" ], "DEF": @@ -32,6 +34,7 @@ "BUFFER_SIZE={BUFFER_SIZE}", "ipconfigDHCP_REGISTER_HOSTNAME=1", "CBMC_REQUIRE_NETWORKBUFFER_ETHERNETBUFFER_NONNULL=1", - "CBMC_GETNETWORKBUFFER_FAILURE_BOUND={FAILURE_BOUND}" + "CBMC_GETNETWORKBUFFER_FAILURE_BOUND={FAILURE_BOUND}", + "ENDPOINT_DNS_ADDRESS_COUNT={ENDPOINT_DNS_ADDRESS_COUNT}" ] } diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/DHCPv6Analyse_harness.c b/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/DHCPv6Analyse_harness.c index bba0186807..cb8a71af06 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/DHCPv6Analyse_harness.c +++ b/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/DHCPv6Analyse_harness.c @@ -52,6 +52,19 @@ BaseType_t __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvDHCPv6Analyse( struct xNetw size_t uxTotalLength, DHCPMessage_IPv6_t * pxDHCPMessage ); +/* prvDHCPv6_handleOption is tested separately. Using mock function in this test case. */ +BaseType_t __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvDHCPv6_handleOption( struct xNetworkEndPoint * pxEndPoint, + uint16_t usOption, + const DHCPOptionSet_t * pxSet, + DHCPMessage_IPv6_t * pxDHCPMessage, + BitConfig_t * pxMessage ) +{ + __CPROVER_assert( __CPROVER_r_ok( pxEndPoint, sizeof( struct xNetworkEndPoint ) ), "pxEndPoint region must be readable" ); + __CPROVER_assert( __CPROVER_r_ok( pxSet, sizeof( DHCPOptionSet_t ) ), "pxSet region must be readable" ); + __CPROVER_assert( __CPROVER_r_ok( pxDHCPMessage, sizeof( DHCPMessage_IPv6_t ) ), "pxDHCPMessage region must be readable" ); + __CPROVER_assert( __CPROVER_r_ok( pxMessage, sizeof( BitConfig_t ) ), "pxMessage region must be readable" ); +} + void harness() { size_t uxTotalLength; diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/Makefile.json b/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/Makefile.json index 08e8432de6..8a2b998f63 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/Makefile.json +++ b/test/cbmc/proofs/DHCPv6/DHCPv6Analyse/Makefile.json @@ -9,7 +9,6 @@ ], "INSTFLAGS": [ - "--remove-function-body __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvDHCPv6_handleOption", "--malloc-may-fail" ], "OPT": diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/DHCPv6HandleOption_harness.c b/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/DHCPv6HandleOption_harness.c index 7a54953136..96b30b73cd 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/DHCPv6HandleOption_harness.c +++ b/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/DHCPv6HandleOption_harness.c @@ -74,6 +74,23 @@ BaseType_t __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvDHCPv6_subOption( uint16_t return nondet_BaseType(); } +uint16_t usBitConfig_read_16( BitConfig_t * pxConfig ) +{ + return ( uint16_t ) nondet_uint32(); +} + +uint8_t ucBitConfig_read_8( BitConfig_t * pxConfig ) +{ + return ( uint8_t ) nondet_uint32(); +} + +BaseType_t xBitConfig_read_uc( BitConfig_t * pxConfig, + uint8_t * pucData, + size_t uxSize ) +{ + return nondet_BaseType(); +} + void harness() { BaseType_t xResult; diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/Makefile.json b/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/Makefile.json index 09859a60b0..ba6dbd18f5 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/Makefile.json +++ b/test/cbmc/proofs/DHCPv6/DHCPv6HandleOption/Makefile.json @@ -5,12 +5,6 @@ "--unwind 2", "--nondet-static --flush" ], - "INSTFLAGS": - [ - "--remove-function-body usBitConfig_read_16", - "--remove-function-body xBitConfig_read_uc", - "--remove-function-body ucBitConfig_read_8" - ], "OPT": [ "--export-file-local-symbols" diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6Process/DHCPv6Process_harness.c b/test/cbmc/proofs/DHCPv6/DHCPv6Process/DHCPv6Process_harness.c index 6e82bf284b..980c620853 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6Process/DHCPv6Process_harness.c +++ b/test/cbmc/proofs/DHCPv6/DHCPv6Process/DHCPv6Process_harness.c @@ -46,6 +46,7 @@ extern Socket_t xDHCPv6Socket; extern DHCPMessage_IPv6_t xDHCPMessage; +extern BaseType_t xDHCPv6SocketUserCount; void __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvCreateDHCPv6Socket( NetworkEndPoint_t * pxEndPoint ); @@ -156,6 +157,8 @@ void harness() { BaseType_t xReset; + __CPROVER_assume( xDHCPv6SocketUserCount >= 0 && xDHCPv6SocketUserCount <= ENDPOINT_DNS_ADDRESS_COUNT ); + NetworkEndPoint_t * pxNetworkEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); __CPROVER_assume( pxNetworkEndPoint != NULL ); diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6Process/Makefile.json b/test/cbmc/proofs/DHCPv6/DHCPv6Process/Makefile.json index 40839470b2..5a2d345cb4 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6Process/Makefile.json +++ b/test/cbmc/proofs/DHCPv6/DHCPv6Process/Makefile.json @@ -1,6 +1,7 @@ { "ENTRY": "DHCPv6Process", "LOOP_UNWIND_COUNT": 4, + "ENDPOINT_DNS_ADDRESS_COUNT": 5, "CBMCFLAGS": [ "--unwind {LOOP_UNWIND_COUNT}", @@ -13,12 +14,16 @@ "DEF": [ "ipconfigUSE_DHCPv6=1", - "FR_RECV_FROM_SUCCESS_COUNT={LOOP_UNWIND_COUNT}" + "FR_RECV_FROM_SUCCESS_COUNT={LOOP_UNWIND_COUNT}", + "ENDPOINT_DNS_ADDRESS_COUNT={ENDPOINT_DNS_ADDRESS_COUNT}" ], "OBJS": [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCPv6.goto" + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCPv6.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto" ] } \ No newline at end of file diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/DHCPv6ProcessEndPoint_harness.c b/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/DHCPv6ProcessEndPoint_harness.c index 9157a86f2e..adf753da71 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/DHCPv6ProcessEndPoint_harness.c +++ b/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/DHCPv6ProcessEndPoint_harness.c @@ -47,6 +47,7 @@ /* Static members defined in FreeRTOS_DHCP.c */ extern Socket_t xDHCPv6Socket; +extern BaseType_t xDHCPv6SocketUserCount; void __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvCreateDHCPv6Socket( NetworkEndPoint_t * pxEndPoint ); BaseType_t __CPROVER_file_local_FreeRTOS_DHCPv6_c_xDHCPv6ProcessEndPoint_HandleState( NetworkEndPoint_t * pxEndPoint, @@ -77,6 +78,18 @@ Socket_t FreeRTOS_socket( BaseType_t xDomain, return pxSocket; } +void vIPNetworkUpCalls( struct xNetworkEndPoint * pxEndPoint ) +{ + __CPROVER_assert( pxEndPoint != NULL, "Endpoint cannot be NULL" ); +} + +void * vSocketClose( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL." ); + + return NULL; +} + /** * For the purpose of this proof we assume that xSocketValid returns true always. * This has to do with assertions in the source code that checks for socket being invalid. @@ -135,6 +148,8 @@ void harness() { BaseType_t xReset, xGivingUp; + __CPROVER_assume( xDHCPv6SocketUserCount >= 0 && xDHCPv6SocketUserCount <= ENDPOINT_DNS_ADDRESS_COUNT ); + NetworkEndPoint_t * pxNetworkEndPoint_Temp = safeMalloc( sizeof( NetworkEndPoint_t ) ); __CPROVER_assume( pxNetworkEndPoint_Temp != NULL ); diff --git a/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/Makefile.json b/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/Makefile.json index d2d5931bcd..25d5a8d6f9 100644 --- a/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/Makefile.json +++ b/test/cbmc/proofs/DHCPv6/DHCPv6ProcessEndPoint/Makefile.json @@ -1,30 +1,26 @@ { "ENTRY": "DHCPv6ProcessEndPoint", + "ENDPOINT_DNS_ADDRESS_COUNT": 5, "CBMCFLAGS": [ "--nondet-static --flush", "--unwind 1" ], - "INSTFLAGS": - [ - "--remove-function-body vIPSetDHCP_RATimerEnableState", - "--remove-function-body vDHCP_RATimerReload", - "--remove-function-body vIPNetworkUpCalls", - "--remove-function-body prvCloseDHCPv6Socket", - "--remove-function-body prvSendDHCPMessage" - ], "OPT": [ "--export-file-local-symbols" ], "DEF": [ - "ipconfigUSE_DHCPv6=1" + "ipconfigUSE_DHCPv6=1", + "ENDPOINT_DNS_ADDRESS_COUNT={ENDPOINT_DNS_ADDRESS_COUNT}" ], "OBJS": [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCPv6.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto" diff --git a/test/cbmc/proofs/DHCPv6/SendDHCPMessage/Makefile.json b/test/cbmc/proofs/DHCPv6/SendDHCPMessage/Makefile.json index 08cb3e73a1..98bc9f7248 100644 --- a/test/cbmc/proofs/DHCPv6/SendDHCPMessage/Makefile.json +++ b/test/cbmc/proofs/DHCPv6/SendDHCPMessage/Makefile.json @@ -4,20 +4,6 @@ [ "--nondet-static" ], - "INSTFLAGS": - [ - "--remove-function-body xApplicationGetRandomNumber", - "--remove-function-body ulApplicationTimeHook", - "--remove-function-body xBitConfig_init", - "--remove-function-body vBitConfig_write_8", - "--remove-function-body vBitConfig_write_uc", - "--remove-function-body vBitConfig_write_16", - "--remove-function-body vBitConfig_write_32", - "--remove-function-body pucBitConfig_peek_last_index_uc", - "--remove-function-body FreeRTOS_inet_pton6", - "--remove-function-body FreeRTOS_sendto", - "--remove-function-body vBitConfig_release" - ], "OPT": [ "--export-file-local-symbols" @@ -29,9 +15,9 @@ "OBJS": [ "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCPv6.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Sockets.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_BitConfig.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DHCPv6.goto" + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto" ] } \ No newline at end of file diff --git a/test/cbmc/proofs/DHCPv6/SendDHCPMessage/SendDHCPMessage_harness.c b/test/cbmc/proofs/DHCPv6/SendDHCPMessage/SendDHCPMessage_harness.c index fc28867207..436b96cf5d 100644 --- a/test/cbmc/proofs/DHCPv6/SendDHCPMessage/SendDHCPMessage_harness.c +++ b/test/cbmc/proofs/DHCPv6/SendDHCPMessage/SendDHCPMessage_harness.c @@ -42,14 +42,103 @@ #include "FreeRTOS_DHCP.h" #include "FreeRTOS_DHCPv6.h" #include "FreeRTOS_ARP.h" +#include "FreeRTOS_BitConfig.h" /* CBMC includes. */ #include "cbmc.h" +void __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvSendDHCPMessage( NetworkEndPoint_t * pxEndPoint ); +BaseType_t xBitConfig_init( BitConfig_t * pxConfig, + const uint8_t * pucData, + size_t uxSize ) +{ + BaseType_t xReturn; -void __CPROVER_file_local_FreeRTOS_DHCPv6_c_prvSendDHCPMessage( NetworkEndPoint_t * pxEndPoint ); + __CPROVER_assert( pxConfig != NULL, "pxConfig cannot be NULL" ); + + if( nondet_bool() ) + { + xReturn = pdTRUE; + + pxConfig->ucContents = safeMalloc( uxSize ); + __CPROVER_assume( pxConfig->ucContents != NULL ); + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + +BaseType_t pucBitConfig_peek_last_index_uc( BitConfig_t * pxConfig, + uint8_t * pucData, + size_t uxSize ) +{ + BaseType_t xReturn; + + __CPROVER_assert( pxConfig != NULL, "pxConfig cannot be NULL" ); + __CPROVER_assert( pucData != NULL, "pucData cannot be NULL" ); + + __CPROVER_assume( xReturn == pdTRUE || xReturn == pdFALSE ); + + return xReturn; +} + +void vBitConfig_write_uc( BitConfig_t * pxConfig, + const uint8_t * pucData, + size_t uxSize ) +{ + __CPROVER_assert( pxConfig != NULL, "pxConfig cannot be NULL" ); + __CPROVER_assert( pucData != NULL, "pucData cannot be NULL" ); +} + +void vBitConfig_write_8( BitConfig_t * pxConfig, + uint8_t ucValue ) +{ + __CPROVER_assert( pxConfig != NULL, "pxConfig cannot be NULL" ); +} +void vBitConfig_write_16( BitConfig_t * pxConfig, + uint16_t usValue ) +{ + __CPROVER_assert( pxConfig != NULL, "pxConfig cannot be NULL" ); +} + +void vBitConfig_write_32( BitConfig_t * pxConfig, + uint32_t ulValue ) +{ + __CPROVER_assert( pxConfig != NULL, "pxConfig cannot be NULL" ); +} + +void vBitConfig_release( BitConfig_t * pxConfig ) +{ + __CPROVER_assert( pxConfig != NULL, "pxConfig cannot be NULL" ); + + if( pxConfig->ucContents != NULL ) + { + free( pxConfig->ucContents ); + } +} + +BaseType_t FreeRTOS_inet_pton6( const char * pcSource, + void * pvDestination ) +{ + BaseType_t xReturn; + + __CPROVER_assert( pcSource != NULL, "pcSource cannot be NULL" ); + __CPROVER_assert( pvDestination != NULL, "pvDestination cannot be NULL" ); + + __CPROVER_assume( xReturn == pdTRUE || xReturn == pdFALSE ); + + return xReturn; +} + +uint32_t ulApplicationTimeHook( void ) +{ + return nondet_uint32(); +} void harness() { diff --git a/test/cbmc/proofs/DNS/CreateDNSMessage/CreateDNSMessage_harness.c b/test/cbmc/proofs/DNS/CreateDNSMessage/CreateDNSMessage_harness.c index 34120f3dbd..76725b659b 100644 --- a/test/cbmc/proofs/DNS/CreateDNSMessage/CreateDNSMessage_harness.c +++ b/test/cbmc/proofs/DNS/CreateDNSMessage/CreateDNSMessage_harness.c @@ -55,6 +55,7 @@ void harness() /* pcHostName is tested to be valid prior */ char * pcHostName = malloc( len ); + __CPROVER_assume( pcHostName != NULL ); if( len && pcHostName ) { @@ -81,6 +82,7 @@ void harness() /* pucUDPPayloadBuffer is tested to be valid prior */ uint8_t * pucUDPPayloadBuffer = malloc( uxExpectedPayloadLength ); + __CPROVER_assume( pucUDPPayloadBuffer != NULL ); __CPROVER_file_local_FreeRTOS_DNS_c_prvCreateDNSMessage( pucUDPPayloadBuffer, pcHostName, uxIdentifier, uxHostType ); } diff --git a/test/cbmc/proofs/DNS/DNSHandlePacket/DNShandlePacket_harness.c b/test/cbmc/proofs/DNS/DNSHandlePacket/DNShandlePacket_harness.c index 983f1f1092..85bb0b8fac 100644 --- a/test/cbmc/proofs/DNS/DNSHandlePacket/DNShandlePacket_harness.c +++ b/test/cbmc/proofs/DNS/DNSHandlePacket/DNShandlePacket_harness.c @@ -7,11 +7,18 @@ #include "FreeRTOS_DNS.h" #include "FreeRTOS_IP_Private.h" -/* Function prvParseDNSReply is proven to be correct separately. */ -uint32_t prvParseDNSReply( uint8_t * pucUDPPayloadBuffer, - size_t xBufferLength, - BaseType_t xExpected ) +/* CBMC includes. */ +#include "cbmc.h" + +/* Function DNS_ParseDNSReply is proven to be correct separately. */ +uint32_t DNS_ParseDNSReply( uint8_t * pucUDPPayloadBuffer, + size_t uxBufferLength, + struct freertos_addrinfo ** ppxAddressInfo, + BaseType_t xExpected, + uint16_t usPort ) { + __CPROVER_assert( pucUDPPayloadBuffer != NULL, "pucUDPPayloadBuffer cannot be NULL" ); + return nondet_uint32(); } void harness() @@ -19,5 +26,7 @@ void harness() NetworkBufferDescriptor_t xNetworkBuffer; xNetworkBuffer.pucEthernetBuffer = malloc( sizeof( UDPPacket_t ) + sizeof( DNSMessage_t ) ); + __CPROVER_assume( xNetworkBuffer.pucEthernetBuffer != NULL ); + ulDNSHandlePacket( &xNetworkBuffer ); } diff --git a/test/cbmc/proofs/DNS/DNSHandlePacket/Makefile.json b/test/cbmc/proofs/DNS/DNSHandlePacket/Makefile.json index 27864b1461..511a166ca5 100644 --- a/test/cbmc/proofs/DNS/DNSHandlePacket/Makefile.json +++ b/test/cbmc/proofs/DNS/DNSHandlePacket/Makefile.json @@ -4,7 +4,8 @@ "OBJS": [ "$(ENTRY)_harness.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto" ], "DEF": [ diff --git a/test/cbmc/proofs/DNS/DNSTreatNBNS/DNS_TreatNBNS_harness.c b/test/cbmc/proofs/DNS/DNSTreatNBNS/DNS_TreatNBNS_harness.c index d6be53942f..cea7f57f53 100644 --- a/test/cbmc/proofs/DNS/DNSTreatNBNS/DNS_TreatNBNS_harness.c +++ b/test/cbmc/proofs/DNS/DNSTreatNBNS/DNS_TreatNBNS_harness.c @@ -38,6 +38,7 @@ #include "cbmc.h" +const BaseType_t xBufferAllocFixedSize = pdFALSE; NetworkBufferDescriptor_t xNetworkBuffer; NetworkBufferDescriptor_t * pxUDPPayloadBuffer_to_NetworkBuffer( const void * pvBuffer ) @@ -67,6 +68,11 @@ NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDe uint8_t * pucNewBuffer = safeMalloc( xNewSizeBytes ); __CPROVER_assume( pucNewBuffer != NULL ); + if( pxNetworkBuffer->pucEthernetBuffer ) + { + free( pxNetworkBuffer->pucEthernetBuffer ); + } + pxNetworkBuffer->pucEthernetBuffer = pucNewBuffer; if( nondet_bool() ) @@ -88,6 +94,26 @@ void prepareReplyDNSMessage( NetworkBufferDescriptor_t * pxNetworkBuffer, __CPROVER_assert( pxNetworkBuffer != NULL, "pxNetworkBuffer: pvBuffer != NULL" ); } +BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, + const char * pcName ) +{ + BaseType_t xReturn; + + __CPROVER_assert( strlen( pcName ) < ipconfigDNS_CACHE_NAME_LENGTH, "The length of domain name must be less than cache size" ); + __CPROVER_assume( xReturn == pdFALSE || xReturn == pdTRUE ); + + return xReturn; +} + +/* vReturnEthernetFrame() is proved separately */ +void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, + BaseType_t xReleaseAfterSend ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, "xNetworkBuffer != NULL" ); + __CPROVER_assert( pxNetworkBuffer->pucEthernetBuffer != NULL, "pxNetworkBuffer->pucEthernetBuffer != NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength ), "Data must be valid" ); +} + void harness() { uint32_t ulIPAddress; @@ -96,16 +122,15 @@ void harness() BaseType_t xDataSize; - /* When re-adjusting the buffer, (sizeof( NBNSAnswer_t ) - 2 * sizeof( uint16_t )) more bytes are - * required to be added to the existing buffer. Make sure total bytes doesn't exceed ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER - * when re-resizing. This will prevent hitting an assert if Buffer Allocation 1 is used. */ - __CPROVER_assume( ( xDataSize != 0 ) && ( xDataSize < ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER - ( sizeof( NBNSAnswer_t ) - 2 * sizeof( uint16_t ) ) ) ) ); + __CPROVER_assume( ( xDataSize > 0 ) && ( xDataSize < ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) ); xNetworkBuffer.pucEthernetBuffer = safeMalloc( xDataSize ); xNetworkBuffer.xDataLength = xDataSize; + __CPROVER_assume( xNetworkBuffer.pucEthernetBuffer != NULL ); if( nondet_bool() ) { + __CPROVER_assume( pxNetworkEndPoint_Temp != NULL ); xNetworkBuffer.pxEndPoint = pxNetworkEndPoint_Temp; } else diff --git a/test/cbmc/proofs/DNS/DNSTreatNBNS/Makefile.json b/test/cbmc/proofs/DNS/DNSTreatNBNS/Makefile.json index 458443eb78..7de551e7c8 100644 --- a/test/cbmc/proofs/DNS/DNSTreatNBNS/Makefile.json +++ b/test/cbmc/proofs/DNS/DNSTreatNBNS/Makefile.json @@ -1,22 +1,29 @@ { "ENTRY": "DNS_TreatNBNS", "USE_CACHE":1, + "NBNS_NAME_MAX_LENGTH":17, "CBMCFLAGS": [ "--unwind 1", - "--unwindset DNS_TreatNBNS.0:16", - "--nondet-static" + "--unwindset DNS_TreatNBNS.0:{NBNS_NAME_MAX_LENGTH}", + "--unwindset prvFindEntryIndex.0:2", + "--unwindset strcmp.0:{NBNS_NAME_MAX_LENGTH}", + "--unwindset strlen.0:{NBNS_NAME_MAX_LENGTH}", + "--unwindset strncpy.0:{NBNS_NAME_MAX_LENGTH}" ], "OBJS": [ "$(ENTRY)_harness.goto", - "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Cache.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto" ], "DEF": [ "ipconfigUSE_DNS_CACHE={USE_CACHE}", - "ipconfigUSE_NBNS=1" + "ipconfigUSE_NBNS=1", + "ipconfigNETWORK_MTU=586" ] } diff --git a/test/cbmc/proofs/DNS/DNSgetHostByName/DNSgetHostByName_harness.c b/test/cbmc/proofs/DNS/DNSgetHostByName/DNSgetHostByName_harness.c index e849b4ee1b..9e5658074a 100644 --- a/test/cbmc/proofs/DNS/DNSgetHostByName/DNSgetHostByName_harness.c +++ b/test/cbmc/proofs/DNS/DNSgetHostByName/DNSgetHostByName_harness.c @@ -17,6 +17,7 @@ #include "NetworkBufferManagement.h" #include "NetworkInterface.h" +/* CBMC includes. */ #include "cbmc.h" uint32_t FreeRTOS_dnslookup( const char * pcHostName ); @@ -37,6 +38,7 @@ size_t __CPROVER_file_local_FreeRTOS_DNS_c_prvCreateDNSMessage( uint8_t * pucUDP const char * pcHostName, TickType_t uxIdentifier, UBaseType_t uxHostType ); +uintptr_t __CPROVER_file_local_FreeRTOS_IP_Utils_c_void_ptr_to_uintptr( const void * pvPointer ); /**************************************************************** * We abstract: @@ -56,6 +58,54 @@ size_t __CPROVER_file_local_FreeRTOS_DNS_c_prvCreateDNSMessage( uint8_t * pucUDP * bound the iterations of strcmp. ****************************************************************/ +/*We assume that the pxGetNetworkBufferWithDescriptor function is implemented correctly and returns a valid data structure. */ +/*This is the mock to mimic the correct expected behavior. If this allocation fails, this might invalidate the proof. */ +NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, + TickType_t xBlockTimeTicks ) +{ + NetworkBufferDescriptor_t * pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + + if( pxNetworkBuffer != NULL ) + { + pxNetworkBuffer->pucEthernetBuffer = safeMalloc( xRequestedSizeBytes + ipUDP_PAYLOAD_IP_TYPE_OFFSET ); + + if( pxNetworkBuffer->pucEthernetBuffer == NULL ) + { + free( pxNetworkBuffer ); + pxNetworkBuffer = NULL; + } + else + { + pxNetworkBuffer->pucEthernetBuffer = ( ( uint8_t * ) pxNetworkBuffer->pucEthernetBuffer ) + ipUDP_PAYLOAD_IP_TYPE_OFFSET; + pxNetworkBuffer->xDataLength = xRequestedSizeBytes; + } + } + + return pxNetworkBuffer; +} + +/* + * In this function, it only allocates network buffer by pxGetNetworkBufferWithDescriptor + * stub function above here. In this case, we should free both network buffer descriptor and pucEthernetBuffer. + */ +void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, + "Precondition: pxNetworkBuffer != NULL" ); + + free( pxNetworkBuffer->pucEthernetBuffer - ipUDP_PAYLOAD_IP_TYPE_OFFSET ); + free( pxNetworkBuffer ); +} + +/* FreeRTOS_ReleaseUDPPayloadBuffer is mocked here and the memory + * is not freed as the buffer allocated by the FreeRTOS_recvfrom is static + * memory */ +void FreeRTOS_ReleaseUDPPayloadBuffer( void * pvBuffer ) +{ + __CPROVER_assert( pvBuffer != NULL, + "FreeRTOS precondition: pvBuffer != NULL" ); +} + /**************************************************************** * Abstract DNS_ParseDNSReply proved memory safe in ParseDNSReply. * @@ -96,6 +146,22 @@ uint32_t DNS_SendRequest( Socket_t xDNSSocket, return ret; } +/**************************************************************** +* Abstract DNS_BindSocket +* +* We stub out this function with return constraint of true or false +* +****************************************************************/ +BaseType_t DNS_BindSocket( Socket_t xSocket, + uint16_t usPort ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdTRUE || xReturn == pdFALSE ); + + return xReturn; +} + /**************************************************************** * Abstract DNS_ReadReply * @@ -106,20 +172,39 @@ BaseType_t DNS_ReadReply( ConstSocket_t xDNSSocket, struct freertos_sockaddr * xAddress, struct xDNSBuffer * pxDNSBuf ) { - BaseType_t ret; int len; + uintptr_t uxTypeOffset; + const uint8_t * pucIPType; + uint8_t ucIPType; + NetworkBufferDescriptor_t * pxNetworkEndPoints; - __CPROVER_assume( ( len > sizeof( DNSMessage_t ) ) && ( len < CBMC_MAX_OBJECT_SIZE ) ); + __CPROVER_assume( ( len > sizeof( DNSMessage_t ) ) && ( len < ipconfigNETWORK_MTU ) ); - pxDNSBuf->pucPayloadBuffer = malloc( len ); + pxNetworkEndPoints = pxGetNetworkBufferWithDescriptor( len, 0 ); + __CPROVER_assume( pxNetworkEndPoints != NULL ); + __CPROVER_assume( pxNetworkEndPoints->pucEthernetBuffer != NULL ); + pxDNSBuf->pucPayloadBuffer = pxNetworkEndPoints->pucEthernetBuffer; pxDNSBuf->uxPayloadLength = len; - __CPROVER_assume( pxDNSBuf->pucPayloadBuffer != NULL ); - __CPROVER_havoc_slice( pxDNSBuf->pucPayloadBuffer, pxDNSBuf->uxPayloadLength ); - return ret; + /* When IPv6 is supported, find out the type of the packet. + * It is stored 48 bytes before the payload buffer as 0x40 or 0x60. */ + uxTypeOffset = __CPROVER_file_local_FreeRTOS_IP_Utils_c_void_ptr_to_uintptr( pxDNSBuf->pucPayloadBuffer ); + uxTypeOffset -= ipUDP_PAYLOAD_IP_TYPE_OFFSET; + pucIPType = ( const uint8_t * ) uxTypeOffset; + + /* For an IPv4 packet, pucIPType points to 6 bytes before the pucEthernetBuffer, + * for a IPv6 packet, pucIPType will point to the first byte of the IP-header: 'ucVersionTrafficClass'. */ + ucIPType = pucIPType[ 0 ] & 0xf0U; + + /* To help the translation from a UDP payload pointer to a networkBuffer, + * a byte was stored at a certain negative offset (-48 bytes). + * It must have a value of either 0x4x or 0x6x. */ + __CPROVER_assume( ( ucIPType == ipTYPE_IPv4 ) || ( ucIPType == ipTYPE_IPv6 ) ); + + return nondet_basetype(); } @@ -177,30 +262,11 @@ size_t __CPROVER_file_local_FreeRTOS_DNS_c_prvCreateDNSMessage( uint8_t * pucUDP return size; } -/*We assume that the pxGetNetworkBufferWithDescriptor function is implemented correctly and returns a valid data structure. */ -/*This is the mock to mimic the correct expected behavior. If this allocation fails, this might invalidate the proof. */ -NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, - TickType_t xBlockTimeTicks ) +uint32_t Prepare_CacheLookup( const char * pcHostName, + BaseType_t xFamily, + struct freertos_addrinfo ** ppxAddressInfo ) { - NetworkBufferDescriptor_t * pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) malloc( sizeof( NetworkBufferDescriptor_t ) ); - - if( pxNetworkBuffer != NULL ) - { - pxNetworkBuffer->pucEthernetBuffer = malloc( xRequestedSizeBytes + ipUDP_PAYLOAD_IP_TYPE_OFFSET ); - - if( pxNetworkBuffer->pucEthernetBuffer == NULL ) - { - free( pxNetworkBuffer ); - pxNetworkBuffer = NULL; - } - else - { - pxNetworkBuffer->pucEthernetBuffer = ( ( uint8_t * ) pxNetworkBuffer->pucEthernetBuffer ) + ipUDP_PAYLOAD_IP_TYPE_OFFSET; - pxNetworkBuffer->xDataLength = xRequestedSizeBytes; - } - } - - return pxNetworkBuffer; + return nondet_uint32(); } /**************************************************************** diff --git a/test/cbmc/proofs/DNS/DNSgetHostByName/Makefile.json b/test/cbmc/proofs/DNS/DNSgetHostByName/Makefile.json index 66b7cad54e..46a0c62cf2 100644 --- a/test/cbmc/proofs/DNS/DNSgetHostByName/Makefile.json +++ b/test/cbmc/proofs/DNS/DNSgetHostByName/Makefile.json @@ -11,6 +11,7 @@ "ENDPOINT_DNS_ADDRESS_COUNT": 5, "HOSTNAME_UNWIND": "__eval {MAX_HOSTNAME_LEN} + 1", "ENDPOINT_DNS_ADDRESS_COUNT_UNWIND": "__eval {ENDPOINT_DNS_ADDRESS_COUNT} + 1", + "DNS_CACHE_ENTRIES": 2, "CBMCFLAGS": [ @@ -30,11 +31,13 @@ "OBJS": [ "$(ENTRY)_harness.goto", - "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "DEF": @@ -42,6 +45,7 @@ "ipconfigUSE_IPv6=1", "ipconfigDNS_USE_CALLBACKS={callback}", "MAX_HOSTNAME_LEN={MAX_HOSTNAME_LEN}", - "ipconfigENDPOINT_DNS_ADDRESS_COUNT={ENDPOINT_DNS_ADDRESS_COUNT}" + "ipconfigENDPOINT_DNS_ADDRESS_COUNT={ENDPOINT_DNS_ADDRESS_COUNT}", + "ipconfigDNS_CACHE_ENTRIES={DNS_CACHE_ENTRIES}" ] } diff --git a/test/cbmc/proofs/DNS/DNSgetHostByName_a/DNSgetHostByName_a_harness.c b/test/cbmc/proofs/DNS/DNSgetHostByName_a/DNSgetHostByName_a_harness.c index 7b7c4a3fb9..03d1ecb736 100644 --- a/test/cbmc/proofs/DNS/DNSgetHostByName_a/DNSgetHostByName_a_harness.c +++ b/test/cbmc/proofs/DNS/DNSgetHostByName_a/DNSgetHostByName_a_harness.c @@ -17,8 +17,11 @@ #include "NetworkBufferManagement.h" #include "NetworkInterface.h" +/* CBMC includes. */ #include "cbmc.h" +uintptr_t __CPROVER_file_local_FreeRTOS_IP_Utils_c_void_ptr_to_uintptr( const void * pvPointer ); + /**************************************************************** * We abstract: * @@ -37,6 +40,54 @@ * bound the iterations of strcmp. ****************************************************************/ +/*We assume that the pxGetNetworkBufferWithDescriptor function is implemented correctly and returns a valid data structure. */ +/*This is the mock to mimic the correct expected behavior. If this allocation fails, this might invalidate the proof. */ +NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, + TickType_t xBlockTimeTicks ) +{ + NetworkBufferDescriptor_t * pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + + if( pxNetworkBuffer != NULL ) + { + pxNetworkBuffer->pucEthernetBuffer = safeMalloc( xRequestedSizeBytes + ipBUFFER_PADDING + ipUDP_PAYLOAD_IP_TYPE_OFFSET ); + + if( pxNetworkBuffer->pucEthernetBuffer == NULL ) + { + free( pxNetworkBuffer ); + pxNetworkBuffer = NULL; + } + else + { + pxNetworkBuffer->pucEthernetBuffer = ( ( uint8_t * ) pxNetworkBuffer->pucEthernetBuffer ) + ipBUFFER_PADDING + ipUDP_PAYLOAD_IP_TYPE_OFFSET; + pxNetworkBuffer->xDataLength = xRequestedSizeBytes; + } + } + + return pxNetworkBuffer; +} + +/* + * In this function, it only allocates network buffer by pxGetNetworkBufferWithDescriptor + * stub function above here. In this case, we should free both network buffer descriptor and pucEthernetBuffer. + */ +void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, + "Precondition: pxNetworkBuffer != NULL" ); + + free( pxNetworkBuffer->pucEthernetBuffer - ( ipUDP_PAYLOAD_IP_TYPE_OFFSET + ipBUFFER_PADDING ) ); + free( pxNetworkBuffer ); +} + +/* FreeRTOS_ReleaseUDPPayloadBuffer is mocked here and the memory + * is not freed as the buffer allocated by the FreeRTOS_recvfrom is static + * memory */ +void FreeRTOS_ReleaseUDPPayloadBuffer( void * pvBuffer ) +{ + __CPROVER_assert( pvBuffer != NULL, + "FreeRTOS precondition: pvBuffer != NULL" ); +} + /**************************************************************** * Abstract DNS_ParseDNSReply proved memory safe in ParseDNSReply. * @@ -111,37 +162,93 @@ BaseType_t NetworkInterfaceOutputFunction_Stub( struct xNetworkInterface * pxDes return ret; } -/*We assume that the pxGetNetworkBufferWithDescriptor function is implemented correctly and returns a valid data structure. */ -/*This is the mock to mimic the correct expected behavior. If this allocation fails, this might invalidate the proof. */ -NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, - TickType_t xBlockTimeTicks ) +Socket_t DNS_CreateSocket( TickType_t uxReadTimeout_ticks ) { - NetworkBufferDescriptor_t * pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) malloc( sizeof( NetworkBufferDescriptor_t ) ); + Socket_t xSock = safeMalloc( sizeof( struct xSOCKET ) ); - if( pxNetworkBuffer != NULL ) - { - pxNetworkBuffer->pucEthernetBuffer = malloc( xRequestedSizeBytes + ipUDP_PAYLOAD_IP_TYPE_OFFSET ); + return xSock; +} - if( pxNetworkBuffer->pucEthernetBuffer == NULL ) - { - free( pxNetworkBuffer ); - pxNetworkBuffer = NULL; - } - else - { - pxNetworkBuffer->pucEthernetBuffer = ( ( uint8_t * ) pxNetworkBuffer->pucEthernetBuffer ) + ipUDP_PAYLOAD_IP_TYPE_OFFSET; - pxNetworkBuffer->xDataLength = xRequestedSizeBytes; - } - } +void DNS_CloseSocket( Socket_t xDNSSocket ) +{ + __CPROVER_assert( xDNSSocket != NULL, "The xDNSSocket cannot be NULL." ); + free( xDNSSocket ); +} - return pxNetworkBuffer; +/**************************************************************** +* Abstract DNS_BindSocket +* +* We stub out this function with return constraint of true or false +* +****************************************************************/ +BaseType_t DNS_BindSocket( Socket_t xSocket, + uint16_t usPort ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdTRUE || xReturn == pdFALSE ); + + return xReturn; } -Socket_t DNS_CreateSocket( TickType_t uxReadTimeout_ticks ) +/**************************************************************** +* Abstract DNS_SendRequest +* +* We stub out this function with return constraint of true or false +* +****************************************************************/ +uint32_t DNS_SendRequest( Socket_t xDNSSocket, + struct freertos_sockaddr * xAddress, + struct xDNSBuffer * pxDNSBuf ) { - Socket_t xSock = safeMalloc( sizeof( struct xSOCKET ) ); + uint32_t ret; - return xSock; + __CPROVER_assume( ret >= 0 ); + __CPROVER_assume( ret <= 1 ); + + return ret; +} + +/**************************************************************** +* Abstract DNS_ReadReply +* +* We stub out this function which returned a dns_buffer filled with random data +* +****************************************************************/ +BaseType_t DNS_ReadReply( ConstSocket_t xDNSSocket, + struct freertos_sockaddr * xAddress, + struct xDNSBuffer * pxDNSBuf ) +{ + int len; + NetworkBufferDescriptor_t * pxNetworkBuffer; + + __CPROVER_assume( ( len > sizeof( DNSMessage_t ) ) && ( len < ipconfigNETWORK_MTU ) ); + + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( len, 0 ); + __CPROVER_assume( pxNetworkBuffer != NULL ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + + pxDNSBuf->pucPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer; + pxDNSBuf->uxPayloadLength = len; + + __CPROVER_havoc_slice( pxDNSBuf->pucPayloadBuffer, pxDNSBuf->uxPayloadLength ); + + return nondet_basetype(); +} + +/* Function xDNSSetCallBack is proven to be correct separately. */ +BaseType_t xDNSSetCallBack( const char * pcHostName, + void * pvSearchID, + FOnDNSEvent pCallbackFunction, + TickType_t xTimeout, + TickType_t xIdentifier, + BaseType_t xIsIPv6 ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdTRUE || xReturn == pdFALSE ); + + return xReturn; } uint32_t Prepare_CacheLookup( const char * pcHostName, diff --git a/test/cbmc/proofs/DNS/DNSgetHostByName_a/Makefile.json b/test/cbmc/proofs/DNS/DNSgetHostByName_a/Makefile.json index f67cb0a113..e4114a1a63 100644 --- a/test/cbmc/proofs/DNS/DNSgetHostByName_a/Makefile.json +++ b/test/cbmc/proofs/DNS/DNSgetHostByName_a/Makefile.json @@ -24,11 +24,12 @@ "OBJS": [ "$(ENTRY)_harness.goto", - "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto" ], "DEF": [ diff --git a/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/DNSgetHostByName_cancel_harness.c b/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/DNSgetHostByName_cancel_harness.c index 4ece6565be..e4ec2ecff5 100644 --- a/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/DNSgetHostByName_cancel_harness.c +++ b/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/DNSgetHostByName_cancel_harness.c @@ -8,6 +8,8 @@ #include "FreeRTOS_DNS.h" #include "FreeRTOS_IP_Private.h" +/* CBMC includes. */ +#include "cbmc.h" /* This proof assumes the length of pcHostName is bounded by MAX_HOSTNAME_LEN. This also abstracts the concurrency. */ @@ -20,27 +22,38 @@ BaseType_t xDNSSetCallBack( const char * pcHostName, TickType_t xIdentifier, BaseType_t xIsIPv6 ); -void * safeMalloc( size_t xWantedSize ) /* Returns a NULL pointer if the wanted size is 0. */ +/* Abstraction of uxListRemove from list. This also abstracts the concurrency. */ +void vListInitialise( List_t * const pxList ) { - if( xWantedSize == 0 ) - { - return NULL; - } + __CPROVER_assert( pxList != NULL, "pxList cannot be NULL" ); - uint8_t byte; + pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); + pxList->xListEnd.xItemValue = portMAX_DELAY; - return byte ? malloc( xWantedSize ) : NULL; + /* The list end next and previous pointers point to itself so we know + * when the list is empty. */ + pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); + pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); + pxList->uxNumberOfItems = ( UBaseType_t ) 0U; } -/* Abstraction of xTaskCheckForTimeOut from task pool. This also abstracts the concurrency. */ -BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, - TickType_t * const pxTicksToWait ) +/* Abstraction of uxListRemove from list. This also abstracts the concurrency. */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) { -} + List_t * const pxList = pxItemToRemove->pxContainer; -/* Abstraction of xTaskResumeAll from task pool. This also abstracts the concurrency. */ -BaseType_t xTaskResumeAll( void ) -{ + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + + pxItemToRemove->pxContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; } /* The function func mimics the callback function.*/ @@ -61,13 +74,11 @@ void harness() size_t len; BaseType_t xReturn; - __CPROVER_assume( len >= 0 && len <= MAX_HOSTNAME_LEN ); + __CPROVER_assume( len > 0 && len <= MAX_HOSTNAME_LEN ); char * pcHostName = safeMalloc( len ); - - if( len && pcHostName ) - { - pcHostName[ len - 1 ] = NULL; - } + __CPROVER_assume( pcHostName != NULL ); + __CPROVER_havoc_slice( pcHostName, len - 1 ); + pcHostName[ len - 1 ] = NULL; xReturn = xDNSSetCallBack( pcHostName, &pvSearchID, pCallback, xTimeout, xIdentifier, xIsIPv6 ); /* Add an item to be able to check the cancel function if the list is non-empty. */ FreeRTOS_gethostbyname_cancel( &pvSearchID ); diff --git a/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/Makefile.json b/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/Makefile.json index 8f568fb540..fc7bfc4c01 100644 --- a/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/Makefile.json +++ b/test/cbmc/proofs/DNS/DNSgetHostByName_cancel/Makefile.json @@ -10,14 +10,18 @@ [ "--unwind 1", "--unwindset prvProcessDNSCache.0:5,strlen.0:{HOSTNAME_UNWIND},__builtin___strcpy_chk.0:{HOSTNAME_UNWIND},vDNSCheckCallBack.0:2,strcpy.0:{HOSTNAME_UNWIND}", - "--nondet-static" + "--unwindset strncpy.0:{HOSTNAME_UNWIND}" ], "OBJS": [ "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS.goto", - "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto", - "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Callback.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "DEF": [ diff --git a/test/cbmc/proofs/DNS/prepareReplyDNSMessage/Makefile.json b/test/cbmc/proofs/DNS/prepareReplyDNSMessage/Makefile.json index f4f366afbf..29e55e2b6f 100644 --- a/test/cbmc/proofs/DNS/prepareReplyDNSMessage/Makefile.json +++ b/test/cbmc/proofs/DNS/prepareReplyDNSMessage/Makefile.json @@ -10,6 +10,7 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_DNS_Parser.goto" ], diff --git a/test/cbmc/proofs/DNS_ParseDNSReply/Configurations.json b/test/cbmc/proofs/DNS_ParseDNSReply/Configurations.json index 80f783f4cd..ae8c857026 100644 --- a/test/cbmc/proofs/DNS_ParseDNSReply/Configurations.json +++ b/test/cbmc/proofs/DNS_ParseDNSReply/Configurations.json @@ -1,16 +1,18 @@ { "ENTRY": "DNS_ParseDNSReply", - "TEST_PAYLOAD_SIZE": 2, - "TEST_IPV4_PACKET_SIZE": 29, - "TEST_IPV6_PACKET_SIZE": 49, + "TEST_MAX_TEST_UNWIND_LOOP": 6, + "TEST_MIN_TEST_DNS_HEADER": 12, + "TEST_MIN_IPV4_UDP_PACKET_SIZE": 42, + "TEST_MIN_IPV6_UDP_PACKET_SIZE": 62, + "TEST_IPV4_NETWORK_MTU": "__eval {TEST_MIN_IPV4_UDP_PACKET_SIZE} + {TEST_MIN_TEST_DNS_HEADER} + {TEST_MAX_TEST_UNWIND_LOOP}", + "TEST_IPV6_NETWORK_MTU": "__eval {TEST_MIN_IPV6_UDP_PACKET_SIZE} + {TEST_MIN_TEST_DNS_HEADER} + {TEST_MAX_TEST_UNWIND_LOOP}", "CBMCFLAGS": [ "--unwind 1", - "--unwindset DNS_ParseDNSReply.0:{TEST_PAYLOAD_SIZE}", - "--unwindset DNS_ReadNameField.0:{TEST_PAYLOAD_SIZE}", - "--unwindset DNS_ReadNameField.1:{TEST_PAYLOAD_SIZE}", - "--unwindset parseDNSAnswer.0:{TEST_PAYLOAD_SIZE}", - "--unwindset strncpy.0:{TEST_PAYLOAD_SIZE}" + "--unwindset strlen.0:{TEST_MAX_TEST_UNWIND_LOOP}", + "--unwindset DNS_ParseDNSReply.0:{TEST_MAX_TEST_UNWIND_LOOP}", + "--unwindset DNS_ReadNameField.0:{TEST_MAX_TEST_UNWIND_LOOP}", + "--unwindset DNS_ReadNameField.1:{TEST_MAX_TEST_UNWIND_LOOP}" ], "OPT": [ @@ -25,21 +27,63 @@ "DEF": [ { - "IPv4": + "IPv4_FixedNetworkBufferSize": [ - "TEST_PACKET_SIZE={TEST_IPV4_PACKET_SIZE}", + "TEST_MAX_PAYLOAD_SIZE={TEST_MAX_TEST_UNWIND_LOOP}", "ipconfigUSE_LLMNR=1", "ipconfigUSE_MDNS=1", - "IS_TESTING_IPV6=0" + "IS_TESTING_IPV6=0", + "IS_BUFFER_ALLOCATE_FIXED=1", + "ipconfigNETWORK_MTU={TEST_IPV4_NETWORK_MTU}", + "ipconfigUSE_TCP=0", + "ipconfigUSE_DHCP=0", + "ipconfigTCP_MSS=536", + "ipconfigDNS_CACHE_NAME_LENGTH={TEST_MAX_TEST_UNWIND_LOOP}" ] }, { - "IPv6": + "IPv6_FixedNetworkBufferSize": [ - "TEST_PACKET_SIZE={TEST_IPV6_PACKET_SIZE}", + "TEST_MAX_PAYLOAD_SIZE={TEST_MAX_TEST_UNWIND_LOOP}", "ipconfigUSE_LLMNR=1", "ipconfigUSE_MDNS=1", - "IS_TESTING_IPV6=1" + "IS_TESTING_IPV6=1", + "IS_BUFFER_ALLOCATE_FIXED=1", + "ipconfigNETWORK_MTU={TEST_IPV6_NETWORK_MTU}", + "ipconfigUSE_TCP=0", + "ipconfigUSE_DHCP=0", + "ipconfigTCP_MSS=536", + "ipconfigDNS_CACHE_NAME_LENGTH={TEST_MAX_TEST_UNWIND_LOOP}" + ] + }, + { + "IPv4_DynamicNetworkBufferSize": + [ + "TEST_MAX_PAYLOAD_SIZE={TEST_MAX_TEST_UNWIND_LOOP}", + "ipconfigUSE_LLMNR=1", + "ipconfigUSE_MDNS=1", + "IS_TESTING_IPV6=0", + "IS_BUFFER_ALLOCATE_FIXED=0", + "ipconfigNETWORK_MTU={TEST_IPV4_NETWORK_MTU}", + "ipconfigUSE_TCP=0", + "ipconfigUSE_DHCP=0", + "ipconfigTCP_MSS=536", + "ipconfigDNS_CACHE_NAME_LENGTH={TEST_MAX_TEST_UNWIND_LOOP}" + ] + }, + { + "IPv6_DynamicNetworkBufferSize": + [ + "TEST_MAX_PAYLOAD_SIZE={TEST_MAX_TEST_UNWIND_LOOP}", + "ipconfigUSE_LLMNR=1", + "ipconfigUSE_MDNS=1", + "IS_TESTING_IPV6=1", + "IS_BUFFER_ALLOCATE_FIXED=0", + "ipconfigNETWORK_MTU={TEST_IPV6_NETWORK_MTU}", + "ipconfigUSE_TCP=0", + "ipconfigUSE_DHCP=0", + "ipconfigTCP_MSS=536", + "ipconfigDNS_CACHE_NAME_LENGTH={TEST_MAX_TEST_UNWIND_LOOP}" ] } ], diff --git a/test/cbmc/proofs/DNS_ParseDNSReply/DNS_ParseDNSReply_harness.c b/test/cbmc/proofs/DNS_ParseDNSReply/DNS_ParseDNSReply_harness.c index 9fae89ddc8..60572ef2df 100644 --- a/test/cbmc/proofs/DNS_ParseDNSReply/DNS_ParseDNSReply_harness.c +++ b/test/cbmc/proofs/DNS_ParseDNSReply/DNS_ParseDNSReply_harness.c @@ -10,6 +10,7 @@ /* FreeRTOS+TCP includes. */ #include "FreeRTOS_IP.h" +#include "FreeRTOS_IP_Private.h" #include "FreeRTOS_DNS.h" #include "FreeRTOS_DNS_Parser.h" #include "NetworkBufferManagement.h" @@ -17,7 +18,8 @@ #include "IPTraceMacroDefaults.h" #include "cbmc.h" -#include "../../utility/memory_assignments.c" + +const BaseType_t xBufferAllocFixedSize = IS_BUFFER_ALLOCATE_FIXED; /**************************************************************** * Signature of function under test @@ -60,12 +62,18 @@ NetworkBufferDescriptor_t * pxUDPPayloadBuffer_to_NetworkBuffer( const void * pv uint32_t ulChar2u32( const uint8_t * pucPtr ) { + uint32_t ret; + __CPROVER_assert( __CPROVER_r_ok( pucPtr, 4 ), "must be 4 bytes legal address to read" ); + return ret; } uint16_t usChar2u16( const uint8_t * pucPtr ) { + uint16_t ret; + __CPROVER_assert( __CPROVER_r_ok( pucPtr, 2 ), "must be 2 bytes legal address to read" ); + return ret; } const char * FreeRTOS_inet_ntop( BaseType_t xAddressFamily, @@ -131,11 +139,14 @@ NetworkBufferDescriptor_t * pxDuplicateNetworkBufferWithDescriptor( const Networ { NetworkBufferDescriptor_t * pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); - if( ensure_memory_is_valid( pxNetworkBuffer, xNewLength ) ) + if( pxNetworkBuffer != NULL ) { pxNetworkBuffer->pucEthernetBuffer = safeMalloc( xNewLength ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); pxNetworkBuffer->xDataLength = xNewLength; + + pxNetworkBuffer->pxEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); + __CPROVER_assume( pxNetworkBuffer->pxEndPoint != NULL ); } return pxNetworkBuffer; @@ -176,23 +187,31 @@ void harness() uint8_t * pPayloadBuffer; size_t uxPayloadBufferLength; - __CPROVER_assert( TEST_PACKET_SIZE < CBMC_MAX_OBJECT_SIZE, - "TEST_PACKET_SIZE < CBMC_MAX_OBJECT_SIZE" ); - - __CPROVER_assume( uxBufferLength < CBMC_MAX_OBJECT_SIZE ); - __CPROVER_assume( uxBufferLength <= TEST_PACKET_SIZE ); + __CPROVER_assume( uxBufferLength <= ipconfigNETWORK_MTU ); + __CPROVER_assume( pxNetworkEndPoint_Temp != NULL ); lIsIPv6Packet = IS_TESTING_IPV6; - xNetworkBuffer.pucEthernetBuffer = safeMalloc( uxBufferLength ); - xNetworkBuffer.xDataLength = uxBufferLength; - xNetworkBuffer.pxEndPoint = pxNetworkEndPoint_Temp; + if( xBufferAllocFixedSize != pdFALSE ) + { + /* When xBufferAllocFixedSize is true, buffers in all network descriptors + * is big enough to allow all Ethernet packet. */ + xNetworkBuffer.pucEthernetBuffer = safeMalloc( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ); + xNetworkBuffer.xDataLength = uxBufferLength; + xNetworkBuffer.pxEndPoint = pxNetworkEndPoint_Temp; + } + else + { + xNetworkBuffer.pucEthernetBuffer = safeMalloc( uxBufferLength ); + xNetworkBuffer.xDataLength = uxBufferLength; + xNetworkBuffer.pxEndPoint = pxNetworkEndPoint_Temp; + } __CPROVER_assume( xNetworkBuffer.pucEthernetBuffer != NULL ); if( lIsIPv6Packet ) { - __CPROVER_assume( uxBufferLength >= ulIpv6UdpOffset ); /* 62 is total size of IPv4 UDP header, including ethernet, IPv6, UDP headers. */ + __CPROVER_assume( uxBufferLength >= ulIpv6UdpOffset ); /* 62 is total size of IPv6 UDP header, including ethernet, IPv6, UDP headers. */ pPayloadBuffer = xNetworkBuffer.pucEthernetBuffer + ulIpv6UdpOffset; uxPayloadBufferLength = uxBufferLength - ulIpv6UdpOffset; } diff --git a/test/cbmc/proofs/IP/ProcessEthernetPacket/Makefile.json b/test/cbmc/proofs/IP/ProcessEthernetPacket/Makefile.json index 4a2b35b440..101f63983f 100644 --- a/test/cbmc/proofs/IP/ProcessEthernetPacket/Makefile.json +++ b/test/cbmc/proofs/IP/ProcessEthernetPacket/Makefile.json @@ -12,6 +12,9 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto" + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto" ] } diff --git a/test/cbmc/proofs/IP/SendEventToIPTask/Makefile.json b/test/cbmc/proofs/IP/SendEventToIPTask/Makefile.json index 30727432c1..dfffab176a 100644 --- a/test/cbmc/proofs/IP/SendEventToIPTask/Makefile.json +++ b/test/cbmc/proofs/IP/SendEventToIPTask/Makefile.json @@ -36,6 +36,8 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", - "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/tasks.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto" ] } diff --git a/test/cbmc/proofs/IP/SendEventToIPTask/SendEventToIPTask_harness.c b/test/cbmc/proofs/IP/SendEventToIPTask/SendEventToIPTask_harness.c index 706bdb9051..665d0ee927 100644 --- a/test/cbmc/proofs/IP/SendEventToIPTask/SendEventToIPTask_harness.c +++ b/test/cbmc/proofs/IP/SendEventToIPTask/SendEventToIPTask_harness.c @@ -36,6 +36,16 @@ #include "FreeRTOS_IP.h" #include "FreeRTOS_IP_Private.h" +/* Abstraction of xIsCallingFromIPTask */ +BaseType_t xIsCallingFromIPTask( void ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + /* The harness test proceeds to call SendEventToIPTask with an unconstrained value */ void harness() { diff --git a/test/cbmc/proofs/Makefile.template b/test/cbmc/proofs/Makefile.template index 094fd560c1..847b0a8f2a 100644 --- a/test/cbmc/proofs/Makefile.template +++ b/test/cbmc/proofs/Makefile.template @@ -105,7 +105,11 @@ $(ENTRY)5.goto: $(ENTRY)4.goto $(GOTO_INSTRUMENT) --drop-unused-functions @RULE_INPUT@ @RULE_OUTPUT@ \ > $(ENTRY)5.txt 2>&1 -$(ENTRY).goto: $(ENTRY)5.goto +$(ENTRY)6.goto: $(ENTRY)5.goto + $(GOTO_INSTRUMENT) --generate-function-body '(?!__CPROVER).*' --generate-function-body-options assert-false @RULE_INPUT@ @RULE_OUTPUT@ \ + > $(ENTRY)6.txt 2>&1 + +$(ENTRY).goto: $(ENTRY)6.goto @CP@ @RULE_INPUT@ @RULE_OUTPUT@ # ____________________________________________________________________ @@ -120,13 +124,13 @@ goto: # report if the proof failed. If the proof failed, we separately fail # the entire job using the check-cbmc-result rule. cbmc.xml: $(ENTRY).goto - -cbmc $(CBMCFLAGS) $(SOLVER) --unwinding-assertions --trace --xml-ui @RULE_INPUT@ > $@ 2>&1 + -cbmc $(CBMCFLAGS) $(SOLVER) --trace --xml-ui @RULE_INPUT@ > $@ 2>&1 property.xml: $(ENTRY).goto - cbmc $(CBMCFLAGS) --unwinding-assertions --show-properties --xml-ui @RULE_INPUT@ > $@ 2>&1 + cbmc $(CBMCFLAGS) --show-properties --xml-ui @RULE_INPUT@ > $@ 2>&1 coverage.xml: $(ENTRY).goto - cbmc $(CBMCFLAGS) --cover location --xml-ui @RULE_INPUT@ > $@ 2>&1 + cbmc $(CBMCFLAGS) --no-standard-checks --malloc-may-fail --malloc-fail-null --cover location --xml-ui @RULE_INPUT@ > $@ 2>&1 cbmc: cbmc.xml diff --git a/test/cbmc/proofs/MakefileCommon.json b/test/cbmc/proofs/MakefileCommon.json index 7ada3e1dca..79e8b7bfbe 100644 --- a/test/cbmc/proofs/MakefileCommon.json +++ b/test/cbmc/proofs/MakefileCommon.json @@ -32,9 +32,7 @@ "CBMCFLAGS ": [ "--object-bits 8", - "--32", - "--bounds-check", - "--pointer-check" + "--32" ], "FORWARD_SLASH": ["/"], diff --git a/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/Makefile.json b/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/Makefile.json index 09f7d0beb9..151aefe2ec 100644 --- a/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/Makefile.json +++ b/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/Makefile.json @@ -8,8 +8,11 @@ "OBJS": [ "$(ENTRY)_harness.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ND.goto" - + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ND.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "DEF": [ diff --git a/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/ProcessICMPMessage_IPv6_harness.c b/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/ProcessICMPMessage_IPv6_harness.c index 990736bc7d..0b02ac8ed2 100644 --- a/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/ProcessICMPMessage_IPv6_harness.c +++ b/test/cbmc/proofs/ND/prvProcessICMPMessage_IPv6/ProcessICMPMessage_IPv6_harness.c @@ -37,7 +37,6 @@ #include "FreeRTOS_ND.h" /* CBMC includes. */ -#include "../../utility/memory_assignments.c" #include "cbmc.h" extern NDCacheRow_t xNDCache[ ipconfigND_CACHE_ENTRIES ]; @@ -70,6 +69,12 @@ void vReceiveNA( const NetworkBufferDescriptor_t * pxNetworkBuffer ) __CPROVER_assert( pxNetworkBuffer != NULL, "The network buffer descriptor cannot be NULL." ); } +/* This function has been tested separately. Therefore, we assume that the implementation is correct. */ +void vReceiveRA( const NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, "The network buffer descriptor cannot be NULL." ); +} + /* This function has been tested separately. Therefore, we assume that the implementation is correct. */ BaseType_t xSendEventStructToIPTask( const IPStackEvent_t * pxEvent, TickType_t uxTimeout ) @@ -103,7 +108,7 @@ NetworkEndPoint_t * FreeRTOS_InterfaceEPInSameSubnet_IPv6( const NetworkInterfac pxEndPoints = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); - if( ensure_memory_is_valid( pxEndPoints, sizeof( NetworkEndPoint_t ) ) ) + if( ( pxEndPoints ) && __CPROVER_w_ok( pxEndPoints, sizeof( NetworkEndPoint_t ) ) ) { /* Interface init. */ pxEndPoints->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); @@ -116,21 +121,32 @@ NetworkEndPoint_t * FreeRTOS_InterfaceEPInSameSubnet_IPv6( const NetworkInterfac return pxEndPoints; } +size_t uxIPHeaderSizePacket( const NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + size_t uxResult; + + __CPROVER_assume( ( uxResult == ipSIZE_OF_IPv4_HEADER ) || ( uxResult == ipSIZE_OF_IPv6_HEADER ) ); + + return uxResult; +} + void harness() { - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); + NetworkBufferDescriptor_t * pxNetworkBuffer; uint32_t ulLen; uint16_t usEthernetBufferSize; - NetworkBufferDescriptor_t xLocalBuffer; + NetworkBufferDescriptor_t * pxLocalARPWaitingNetworkBuffer; + + __CPROVER_assume( ( ulLen >= sizeof( ICMPPacket_IPv6_t ) ) && ( ulLen < ipconfigNETWORK_MTU ) ); + + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ulLen, 0 ); /* The code does not expect pxNetworkBuffer to be NULL. */ __CPROVER_assume( pxNetworkBuffer != NULL ); - - __CPROVER_assume( ( ulLen >= sizeof( ICMPPacket_IPv6_t ) ) && ( ulLen < ipconfigNETWORK_MTU ) ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + __CPROVER_havoc_slice( pxNetworkBuffer->pucEthernetBuffer, ulLen ); pxNetworkBuffer->xDataLength = ulLen; - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( ulLen ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); /* Add an end point to the network buffer present. Its assumed that the * network interface layer correctly assigns the end point to the generated buffer. */ @@ -147,19 +163,20 @@ void harness() /* The packet must at least be as big as an IPv6 Packet. The size is not * checked in the function as the pointer is stored by the IP-task itself * and therefore it will always be of the required size. */ - __CPROVER_assume( usEthernetBufferSize >= sizeof( IPPacket_IPv6_t ) ); - - /* Add matching data length to the network buffer descriptor. */ - __CPROVER_assume( xLocalBuffer.xDataLength == usEthernetBufferSize ); - - xLocalBuffer.pucEthernetBuffer = safeMalloc( usEthernetBufferSize ); + __CPROVER_assume( ( usEthernetBufferSize >= sizeof( IPPacket_IPv6_t ) ) && ( usEthernetBufferSize < ipconfigNETWORK_MTU ) ); + pxLocalARPWaitingNetworkBuffer = pxGetNetworkBufferWithDescriptor( usEthernetBufferSize, 0 ); /* Since this pointer is maintained by the IP-task, either the pointer - * pxARPWaitingNetworkBuffer will be NULL or xLocalBuffer.pucEthernetBuffer + * pxARPWaitingNetworkBuffer will be NULL or pxLocalARPWaitingNetworkBuffer.pucEthernetBuffer * will be non-NULL. */ - __CPROVER_assume( xLocalBuffer.pucEthernetBuffer != NULL ); + __CPROVER_assume( pxLocalARPWaitingNetworkBuffer != NULL ); + __CPROVER_assume( pxLocalARPWaitingNetworkBuffer->pucEthernetBuffer != NULL ); + __CPROVER_havoc_slice( pxLocalARPWaitingNetworkBuffer->pucEthernetBuffer, usEthernetBufferSize ); + + /* Add matching data length to the network buffer descriptor. */ + pxLocalARPWaitingNetworkBuffer->xDataLength = usEthernetBufferSize; - pxARPWaitingNetworkBuffer = &xLocalBuffer; + pxARPWaitingNetworkBuffer = pxLocalARPWaitingNetworkBuffer; } else { diff --git a/test/cbmc/proofs/ND/prvReturnICMP_IPv6/Makefile.json b/test/cbmc/proofs/ND/prvReturnICMP_IPv6/Makefile.json index cdc3a4f0a2..47de0cd15d 100644 --- a/test/cbmc/proofs/ND/prvReturnICMP_IPv6/Makefile.json +++ b/test/cbmc/proofs/ND/prvReturnICMP_IPv6/Makefile.json @@ -8,8 +8,11 @@ "OBJS": [ "$(ENTRY)_harness.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ND.goto" - + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ND.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "INC": [ diff --git a/test/cbmc/proofs/ND/prvReturnICMP_IPv6/ReturnICMP_IPv6_harness.c b/test/cbmc/proofs/ND/prvReturnICMP_IPv6/ReturnICMP_IPv6_harness.c index b40437501a..e0340a76cd 100644 --- a/test/cbmc/proofs/ND/prvReturnICMP_IPv6/ReturnICMP_IPv6_harness.c +++ b/test/cbmc/proofs/ND/prvReturnICMP_IPv6/ReturnICMP_IPv6_harness.c @@ -37,7 +37,6 @@ #include "FreeRTOS_ND.h" /* CBMC includes. */ -#include "../../utility/memory_assignments.c" #include "cbmc.h" extern NDCacheRow_t xNDCache[ ipconfigND_CACHE_ENTRIES ]; @@ -72,6 +71,12 @@ void vReceiveNA( const NetworkBufferDescriptor_t * pxNetworkBuffer ) __CPROVER_assert( pxNetworkBuffer->pucEthernetBuffer != NULL, "The Ethernet buffer cannot be NULL." ); } +/* This function has been tested separately. Therefore, we assume that the implementation is correct. */ +void vReceiveRA( const NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, "The network buffer descriptor cannot be NULL." ); +} + /* This function has been tested separately. Therefore, we assume that the implementation is correct. */ BaseType_t xSendEventStructToIPTask( const IPStackEvent_t * pxEvent, TickType_t uxTimeout ) @@ -106,7 +111,7 @@ NetworkEndPoint_t * FreeRTOS_InterfaceEPInSameSubnet_IPv6( const NetworkInterfac pxEndPoints = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); - if( ensure_memory_is_valid( pxEndPoints, sizeof( NetworkEndPoint_t ) ) ) + if( ( pxEndPoints ) && __CPROVER_w_ok( pxEndPoints, sizeof( NetworkEndPoint_t ) ) ) { /* Interface init. */ pxEndPoints->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); @@ -119,21 +124,33 @@ NetworkEndPoint_t * FreeRTOS_InterfaceEPInSameSubnet_IPv6( const NetworkInterfac return pxEndPoints; } +size_t uxIPHeaderSizePacket( const NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + size_t uxResult; + + __CPROVER_assume( ( uxResult == ipSIZE_OF_IPv4_HEADER ) || ( uxResult == ipSIZE_OF_IPv6_HEADER ) ); + + return uxResult; +} + void harness() { - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); + NetworkBufferDescriptor_t * pxNetworkBuffer; uint32_t ulLen; - NetworkBufferDescriptor_t xLocalBuffer; + NetworkBufferDescriptor_t * pxLocalARPWaitingNetworkBuffer; uint16_t usEthernetBufferSize; - /* The code does not expect both of these to be equal to NULL at the same time. */ - __CPROVER_assume( pxNetworkBuffer != NULL ); - __CPROVER_assume( ( ulLen >= sizeof( ICMPPacket_IPv6_t ) ) && ( ulLen < ipconfigNETWORK_MTU ) ); + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ulLen, 0 ); + + /* The code does not expect pxNetworkBuffer to be NULL. */ + __CPROVER_assume( pxNetworkBuffer != NULL ); + pxNetworkBuffer->xDataLength = ulLen; pxNetworkBuffer->pucEthernetBuffer = safeMalloc( ulLen ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + __CPROVER_havoc_slice( pxNetworkBuffer->pucEthernetBuffer, ulLen ); /* Add an end point to the network buffer present. Its assumed that the * network interface layer correctly assigns the end point to the generated buffer. */ @@ -149,19 +166,20 @@ void harness() /* The packet must at least be as big as an IPv6 Packet. The size is not * checked in the function as the pointer is stored by the IP-task itself * and therefore it will always be of the required size. */ - __CPROVER_assume( usEthernetBufferSize >= sizeof( IPPacket_IPv6_t ) ); - - /* Add matching data length to the network buffer descriptor. */ - __CPROVER_assume( xLocalBuffer.xDataLength == usEthernetBufferSize ); - - xLocalBuffer.pucEthernetBuffer = safeMalloc( usEthernetBufferSize ); + __CPROVER_assume( ( usEthernetBufferSize >= sizeof( IPPacket_IPv6_t ) ) && ( usEthernetBufferSize < ipconfigNETWORK_MTU ) ); + pxLocalARPWaitingNetworkBuffer = pxGetNetworkBufferWithDescriptor( usEthernetBufferSize, 0 ); /* Since this pointer is maintained by the IP-task, either the pointer - * pxARPWaitingNetworkBuffer will be NULL or xLocalBuffer.pucEthernetBuffer + * pxARPWaitingNetworkBuffer will be NULL or pxLocalARPWaitingNetworkBuffer.pucEthernetBuffer * will be non-NULL. */ - __CPROVER_assume( xLocalBuffer.pucEthernetBuffer != NULL ); + __CPROVER_assume( pxLocalARPWaitingNetworkBuffer != NULL ); + __CPROVER_assume( pxLocalARPWaitingNetworkBuffer->pucEthernetBuffer != NULL ); + __CPROVER_havoc_slice( pxLocalARPWaitingNetworkBuffer->pucEthernetBuffer, usEthernetBufferSize ); + + /* Add matching data length to the network buffer descriptor. */ + pxLocalARPWaitingNetworkBuffer->xDataLength = usEthernetBufferSize; - pxARPWaitingNetworkBuffer = &xLocalBuffer; + pxARPWaitingNetworkBuffer = pxLocalARPWaitingNetworkBuffer; prvProcessICMPMessage_IPv6( pxNetworkBuffer ); } diff --git a/test/cbmc/proofs/RA/vReceiveRA/Makefile.json b/test/cbmc/proofs/RA/vReceiveRA/Makefile.json index 8b995fc8d1..1a4edbd460 100644 --- a/test/cbmc/proofs/RA/vReceiveRA/Makefile.json +++ b/test/cbmc/proofs/RA/vReceiveRA/Makefile.json @@ -4,6 +4,7 @@ [ "--unwind 2", "--unwindset FreeRTOS_NextEndPoint.0:1", + "--unwindset FreeRTOS_CreateIPv6Address.0:5", "--nondet-static" ], "OPT": @@ -13,8 +14,13 @@ "OBJS": [ "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_RA.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_RA.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_ND.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "INC": diff --git a/test/cbmc/proofs/RA/vReceiveRA/ReceiveRA_harness.c b/test/cbmc/proofs/RA/vReceiveRA/ReceiveRA_harness.c index e7f6cf5051..424c458326 100644 --- a/test/cbmc/proofs/RA/vReceiveRA/ReceiveRA_harness.c +++ b/test/cbmc/proofs/RA/vReceiveRA/ReceiveRA_harness.c @@ -37,7 +37,6 @@ #include "FreeRTOS_ND.h" /* CBMC includes. */ -#include "../../utility/memory_assignments.c" #include "cbmc.h" /* This function has been tested separately. Therefore, we assume that the implementation is correct. */ @@ -45,6 +44,11 @@ ICMPPrefixOption_IPv6_t * __CPROVER_file_local_FreeRTOS_RA_c_vReceiveRA_ReadRepl { ICMPPrefixOption_IPv6_t * pxPrefixOption = safeMalloc( sizeof( ICMPPrefixOption_IPv6_t ) ); + if( pxPrefixOption ) + { + __CPROVER_assume( ( pxPrefixOption->ucPrefixLength > 0U ) && ( pxPrefixOption->ucPrefixLength <= ( 8U * ipSIZE_OF_IPv6_ADDRESS ) ) ); + } + return pxPrefixOption; } @@ -75,30 +79,56 @@ void vNDSendRouterSolicitation( NetworkBufferDescriptor_t * pxNetworkBuffer, __CPROVER_assert( pxIPAddress != NULL, "The pxIPAddress cannot be NULL." ); } -void harness() +/* The checksum generation is stubbed out since the actual checksum + * does not matter. The stub will return an indeterminate value each time. */ +uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, + size_t uxBufferLength, + BaseType_t xOutgoingPacket ) { - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); - NetworkInterface_t * pxInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); - uint32_t ulLen; + __CPROVER_assert( pucEthernetBuffer != NULL, "Ethernet buffer cannot be NULL" ); - /* The code does not expect pxNetworkBuffer to be NULL. */ - __CPROVER_assume( pxNetworkBuffer != NULL ); - - __CPROVER_assume( ( ulLen >= sizeof( ICMPPacket_IPv6_t ) ) && ( ulLen < ipconfigNETWORK_MTU ) ); - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( ulLen ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + /* Return an indeterminate value. */ + return ( uint16_t ) nondet_uint32(); +} - pxNetworkBuffer->pxInterface = safeMalloc( sizeof( NetworkInterface_t ) ); - __CPROVER_assume( pxNetworkBuffer->pxInterface != NULL ); +/* vReturnEthernetFrame() is proved separately */ +void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, + BaseType_t xReleaseAfterSend ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, "xNetworkBuffer != NULL" ); + __CPROVER_assert( pxNetworkBuffer->pucEthernetBuffer != NULL, "pxNetworkBuffer->pucEthernetBuffer != NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength ), "Data must be valid" ); +} - pxNetworkBuffer->pxEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); +void harness() +{ + NetworkBufferDescriptor_t * pxNetworkBuffer; + NetworkInterface_t * pxInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); + uint32_t ulLen; /* Initialize global Endpoint variable */ pxNetworkEndPoints = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); __CPROVER_assume( pxNetworkEndPoints != NULL ); - pxNetworkEndPoints->pxNetworkInterface = pxNetworkBuffer->pxInterface; + pxNetworkEndPoints->pxNetworkInterface = safeMalloc( sizeof( NetworkInterface_t ) ); + __CPROVER_assume( pxNetworkEndPoints->pxNetworkInterface != NULL ); __CPROVER_assume( pxNetworkEndPoints->pxNetworkInterface != NULL ); pxNetworkEndPoints->pxNext = NULL; + /* Initialize network buffer. */ + __CPROVER_assume( ( ulLen >= sizeof( ICMPPacket_IPv6_t ) ) && ( ulLen < ipconfigNETWORK_MTU ) ); + + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ulLen, 0 ); + + /* The code does not expect pxNetworkBuffer to be NULL. */ + __CPROVER_assume( pxNetworkBuffer != NULL ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + __CPROVER_havoc_slice( pxNetworkBuffer->pucEthernetBuffer, ulLen ); + + pxNetworkBuffer->pxInterface = pxNetworkEndPoints->pxNetworkInterface; + pxNetworkBuffer->pxEndPoint = pxNetworkEndPoints; + + /* The prefix length must be equal to or less than 128 to avoid assertion in FreeRTOS_CreateIPv6Address(). */ + __CPROVER_assume( ( pxNetworkEndPoints->ipv6_settings.uxPrefixLength > 0U ) && ( pxNetworkEndPoints->ipv6_settings.uxPrefixLength <= ( 8U * ipSIZE_OF_IPv6_ADDRESS ) ) ); + vReceiveRA( pxNetworkBuffer ); } diff --git a/test/cbmc/proofs/RA/vReceiveRA_ReadReply/Makefile.json b/test/cbmc/proofs/RA/vReceiveRA_ReadReply/Makefile.json index 61d93b3d5d..91ff527323 100644 --- a/test/cbmc/proofs/RA/vReceiveRA_ReadReply/Makefile.json +++ b/test/cbmc/proofs/RA/vReceiveRA_ReadReply/Makefile.json @@ -12,6 +12,7 @@ "OBJS": [ "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_RA.goto" ], diff --git a/test/cbmc/proofs/Routing/MatchingEndpoint/MatchingEndpoint_harness.c b/test/cbmc/proofs/Routing/MatchingEndpoint/MatchingEndpoint_harness.c index dbcde05c02..1496562b1b 100644 --- a/test/cbmc/proofs/Routing/MatchingEndpoint/MatchingEndpoint_harness.c +++ b/test/cbmc/proofs/Routing/MatchingEndpoint/MatchingEndpoint_harness.c @@ -39,6 +39,16 @@ #include "../../utility/memory_assignments.c" #include "cbmc.h" +/* Abstraction of xIsIPv6Loopback returns either true or false. */ +BaseType_t xIsIPv6Loopback( const IPv6_Address_t * pxAddress ) +{ + BaseType_t xReturn; + + __CPROVER_assume( xReturn == pdTRUE || xReturn == pdFALSE ); + + return xReturn; +} + void harness() { NetworkInterface_t * pxNetworkInterface = safeMalloc( sizeof( NetworkInterface_t ) ); diff --git a/test/cbmc/proofs/Socket/lTCPAddRxdata/TCPAddRxdata_harness.c b/test/cbmc/proofs/Socket/lTCPAddRxdata/TCPAddRxdata_harness.c index 6e0b9278a2..c8a7953453 100644 --- a/test/cbmc/proofs/Socket/lTCPAddRxdata/TCPAddRxdata_harness.c +++ b/test/cbmc/proofs/Socket/lTCPAddRxdata/TCPAddRxdata_harness.c @@ -34,11 +34,45 @@ void * pvPortMallocLarge( size_t xWantedSize ) return safeMalloc( xWantedSize ); } +size_t uxStreamBufferFrontSpace( const StreamBuffer_t * const pxBuffer ) +{ + size_t uxReturn; + + return uxReturn; +} + +BaseType_t xSendEventToIPTask( eIPEvent_t eEvent ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + +void vTCPStateChange( FreeRTOS_Socket_t * pxSocket, + enum eTCP_STATE eTCPState ) +{ +} + +size_t uxStreamBufferAdd( StreamBuffer_t * const pxBuffer, + size_t uxOffset, + const uint8_t * const pucData, + size_t uxByteCount ) +{ + size_t uxReturn; + + __CPROVER_assert( __CPROVER_r_ok( pucData, uxByteCount ), "Data pointer must be valid to read" ); + __CPROVER_assume( uxReturn <= uxByteCount ); + + return uxReturn; +} + void harness() { FreeRTOS_Socket_t * pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); size_t uxOffset; - const uint8_t * pcData; + const uint8_t * pcData = NULL; uint32_t ulByteCount; /* This function expect socket to be not NULL, as it has been validated previously */ @@ -48,7 +82,12 @@ void harness() __CPROVER_assume( pxSocket->u.xTCP.uxRxStreamSize >= 0 && pxSocket->u.xTCP.uxRxStreamSize < ipconfigTCP_RX_BUFFER_LENGTH ); __CPROVER_assume( pxSocket->u.xTCP.uxTxStreamSize >= 0 && pxSocket->u.xTCP.uxTxStreamSize < ipconfigTCP_TX_BUFFER_LENGTH ); + /* ipconfigTCP_MSS is guaranteed not less than tcpMINIMUM_SEGMENT_LENGTH by FreeRTOSIPConfigDefaults.h */ + __CPROVER_assume( pxSocket->u.xTCP.usMSS >= tcpMINIMUM_SEGMENT_LENGTH ); + + __CPROVER_assume( ulByteCount > 0U ); pcData = safeMalloc( ulByteCount ); + __CPROVER_assume( pcData != NULL ); lTCPAddRxdata( pxSocket, uxOffset, pcData, ulByteCount ); } diff --git a/test/cbmc/proofs/Socket/vSocketBind/ALLOW_ETHERNET_DRIVER_FILTERS_PACKETS/Makefile.json b/test/cbmc/proofs/Socket/vSocketBind/ALLOW_ETHERNET_DRIVER_FILTERS_PACKETS/Makefile.json index 379ae7a399..336e6d2ece 100644 --- a/test/cbmc/proofs/Socket/vSocketBind/ALLOW_ETHERNET_DRIVER_FILTERS_PACKETS/Makefile.json +++ b/test/cbmc/proofs/Socket/vSocketBind/ALLOW_ETHERNET_DRIVER_FILTERS_PACKETS/Makefile.json @@ -13,7 +13,8 @@ "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Routing.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Sockets.goto", - "$(ENTRY)_harness.goto" + "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto" ], "INSTFLAGS": [ diff --git a/test/cbmc/proofs/Socket/vSocketClose/Configurations.json b/test/cbmc/proofs/Socket/vSocketClose/Configurations.json index 50df094177..f36f3dc532 100644 --- a/test/cbmc/proofs/Socket/vSocketClose/Configurations.json +++ b/test/cbmc/proofs/Socket/vSocketClose/Configurations.json @@ -9,6 +9,7 @@ [ "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Sockets.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", "$(ENTRY)_harness.goto" ], "DEF": diff --git a/test/cbmc/proofs/TCP/prvHandleListen/Makefile.json b/test/cbmc/proofs/TCP/prvHandleListen/Makefile.json index 856e50c30c..ab47b60c1b 100644 --- a/test/cbmc/proofs/TCP/prvHandleListen/Makefile.json +++ b/test/cbmc/proofs/TCP/prvHandleListen/Makefile.json @@ -9,6 +9,7 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_State_Handling.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_State_Handling_IPv4.goto" ], @@ -19,7 +20,6 @@ ], "INSTFLAGS": [ - "--remove-function-body prvTCPSendReset" ], "INC": [ diff --git a/test/cbmc/proofs/TCP/prvHandleListen/prvHandleListen_harness.c b/test/cbmc/proofs/TCP/prvHandleListen/prvHandleListen_harness.c index a742293721..3fa5aadd81 100644 --- a/test/cbmc/proofs/TCP/prvHandleListen/prvHandleListen_harness.c +++ b/test/cbmc/proofs/TCP/prvHandleListen/prvHandleListen_harness.c @@ -53,6 +53,66 @@ Socket_t FreeRTOS_socket( BaseType_t xDomain, return ensure_FreeRTOS_Socket_t_is_allocated(); } +BaseType_t vSocketBind( FreeRTOS_Socket_t * pxSocket, + struct freertos_sockaddr * pxBindAddress, + size_t uxAddressLength, + BaseType_t xInternal ) +{ + BaseType_t xRet; + + __CPROVER_assert( pxSocket != NULL, + "FreeRTOS precondition: pxSocket != NULL" ); + __CPROVER_assert( pxBindAddress != NULL, + "FreeRTOS precondition: pxBindAddress != NULL" ); + + return xRet; +} + +void * vSocketClose( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL" ); + + return NULL; +} + +BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + +void vTCPStateChange( FreeRTOS_Socket_t * pxSocket, + enum eTCP_STATE eTCPState ) +{ +} + +BaseType_t prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + +void prvSocketSetMSS( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); +} + +size_t FreeRTOS_GetLocalAddress( ConstSocket_t xSocket, + struct freertos_sockaddr * pxAddress ) +{ + size_t uxReturn; + + __CPROVER_assert( pxAddress != NULL, "pxAddress cannot be NULL" ); + + return uxReturn; +} + void harness() { size_t xDataLength; diff --git a/test/cbmc/proofs/TCP/prvHandleListen_IPv6/Makefile.json b/test/cbmc/proofs/TCP/prvHandleListen_IPv6/Makefile.json index aa1ee4f706..b824b9a396 100644 --- a/test/cbmc/proofs/TCP/prvHandleListen_IPv6/Makefile.json +++ b/test/cbmc/proofs/TCP/prvHandleListen_IPv6/Makefile.json @@ -11,6 +11,7 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_State_Handling.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_State_Handling_IPv6.goto" ], @@ -21,7 +22,6 @@ ], "INSTFLAGS": [ - "--remove-function-body prvTCPSendReset" ], "INC": [ diff --git a/test/cbmc/proofs/TCP/prvHandleListen_IPv6/prvHandleListen_IPv6_harness.c b/test/cbmc/proofs/TCP/prvHandleListen_IPv6/prvHandleListen_IPv6_harness.c index 5134b5bca1..8be5891f9c 100644 --- a/test/cbmc/proofs/TCP/prvHandleListen_IPv6/prvHandleListen_IPv6_harness.c +++ b/test/cbmc/proofs/TCP/prvHandleListen_IPv6/prvHandleListen_IPv6_harness.c @@ -53,6 +53,66 @@ Socket_t FreeRTOS_socket( BaseType_t xDomain, return ensure_FreeRTOS_Socket_t_is_allocated(); } +BaseType_t vSocketBind( FreeRTOS_Socket_t * pxSocket, + struct freertos_sockaddr * pxBindAddress, + size_t uxAddressLength, + BaseType_t xInternal ) +{ + BaseType_t xRet; + + __CPROVER_assert( pxSocket != NULL, + "FreeRTOS precondition: pxSocket != NULL" ); + __CPROVER_assert( pxBindAddress != NULL, + "FreeRTOS precondition: pxBindAddress != NULL" ); + + return xRet; +} + +void * vSocketClose( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL" ); + + return NULL; +} + +void prvSocketSetMSS( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); +} + +BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + +void vTCPStateChange( FreeRTOS_Socket_t * pxSocket, + enum eTCP_STATE eTCPState ) +{ +} + +BaseType_t prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + +size_t FreeRTOS_GetLocalAddress( ConstSocket_t xSocket, + struct freertos_sockaddr * pxAddress ) +{ + size_t uxReturn; + + __CPROVER_assert( pxAddress != NULL, "pxAddress cannot be NULL" ); + + return uxReturn; +} + void harness() { size_t xDataLength; diff --git a/test/cbmc/proofs/TCP/prvSendData/Makefile.json b/test/cbmc/proofs/TCP/prvSendData/Makefile.json index cfc73e67ea..f8b8a29f1d 100644 --- a/test/cbmc/proofs/TCP/prvSendData/Makefile.json +++ b/test/cbmc/proofs/TCP/prvSendData/Makefile.json @@ -8,7 +8,8 @@ "OBJS": [ "$(ENTRY)_harness.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "INC": [ diff --git a/test/cbmc/proofs/TCP/prvSendData/SendData_harness.c b/test/cbmc/proofs/TCP/prvSendData/SendData_harness.c index 83da8405bb..1f76a23fcd 100644 --- a/test/cbmc/proofs/TCP/prvSendData/SendData_harness.c +++ b/test/cbmc/proofs/TCP/prvSendData/SendData_harness.c @@ -36,7 +36,7 @@ #include "FreeRTOS_TCP_IP.h" /* CBMC includes. */ -#include "../../utility/memory_assignments.c" +#include "cbmc.h" /**************************************************************** * Declare the IP Header Size external to the harness so it can be @@ -52,15 +52,75 @@ size_t uxIPHeaderSizePacket( const NetworkBufferDescriptor_t * pxNetworkBuffer ) return uxIPHeaderSizePacket_uxResult; } +void prvTCPReturnPacket( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t * pxDescriptor, + uint32_t ulLen, + BaseType_t xReleaseAfterSend ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket should not be NULL" ); + __CPROVER_assert( pxDescriptor != NULL, "pxDescriptor should not be NULL" ); + __CPROVER_assert( pxDescriptor->pucEthernetBuffer != NULL, "pucEthernetBuffer should not be NULL" ); +} + +void prvTCPReturnPacket_IPV4( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t * pxDescriptor, + uint32_t ulLen, + BaseType_t xReleaseAfterSend ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket should not be NULL" ); + __CPROVER_assert( pxDescriptor != NULL, "pxDescriptor should not be NULL" ); + __CPROVER_assert( pxDescriptor->pucEthernetBuffer != NULL, "pucEthernetBuffer should not be NULL" ); +} + +/* Memory assignment for FreeRTOS_Socket_t */ +FreeRTOS_Socket_t * ensure_FreeRTOS_Socket_t_is_allocated() +{ + size_t buf_size; /* Give buffer_size an unconstrained value */ + FreeRTOS_Socket_t * pxSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) ); + + __CPROVER_assume( pxSocket != NULL ); + pxSocket->u.xTCP.rxStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.txStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.pxPeerSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) ); + pxSocket->pxEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); + pxSocket->u.xTCP.pxAckMessage = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + + if( pxSocket->u.xTCP.pxAckMessage != NULL ) + { + __CPROVER_assume( ( buf_size > ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + sizeof( TCPHeader_t ) ) ) && ( buf_size < ipconfigNETWORK_MTU ) ); + pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer = safeMalloc( buf_size ); + __CPROVER_assume( pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer != NULL ); + } + + return pxSocket; +} + +/* + * In this function, it only allocates network buffer by harness. + */ +void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, + "Precondition: pxNetworkBuffer != NULL" ); + + if( pxNetworkBuffer->pucEthernetBuffer != NULL ) + { + free( pxNetworkBuffer->pucEthernetBuffer ); + } + + free( pxNetworkBuffer ); +} + void harness() { FreeRTOS_Socket_t * pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); + NetworkBufferDescriptor_t * pxNetworkBuffer; uint32_t ulReceiveLength; BaseType_t xByteCount; size_t buf_size; /* Give buffer_size an unconstrained value */ /* The code does not expect pxSocket/pxNetworkBuffer to be equal to NULL. */ + pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); __CPROVER_assume( pxSocket != NULL ); __CPROVER_assume( pxNetworkBuffer != NULL ); @@ -73,7 +133,7 @@ void harness() uxIPHeaderSizePacket_uxResult = ipSIZE_OF_IPv4_HEADER; } - __CPROVER_assume( buf_size > ( ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket_uxResult + sizeof( TCPHeader_t ) ) ); + __CPROVER_assume( ( buf_size > ( ipSIZE_OF_ETH_HEADER + uxIPHeaderSizePacket_uxResult + sizeof( TCPHeader_t ) ) ) && ( buf_size < ipconfigNETWORK_MTU ) ); pxNetworkBuffer->pucEthernetBuffer = safeMalloc( buf_size ); __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); diff --git a/test/cbmc/proofs/TCP/prvTCPHandleState/Makefile.json b/test/cbmc/proofs/TCP/prvTCPHandleState/Makefile.json index c82fbddc3a..bc6f29b9c1 100644 --- a/test/cbmc/proofs/TCP/prvTCPHandleState/Makefile.json +++ b/test/cbmc/proofs/TCP/prvTCPHandleState/Makefile.json @@ -45,18 +45,21 @@ "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Reception.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto" ], "DEF": [ + "ipconfigUSE_TCP=1", "ipconfigZERO_COPY_TX_DRIVER={TX_DRIVER}", "ipconfigUSE_LINKED_RX_MESSAGES={RX_MESSAGES}", - "FREERTOS_TCP_ENABLE_VERIFICATION" + "FREERTOS_TCP_ENABLE_VERIFICATION", + "ipconfigNETWORK_MTU=586" ], "INSTFLAGS": [ - "--remove-function-body prvTCPPrepareSend", - "--remove-function-body prvTCPReturnPacket" ], "INC": [ diff --git a/test/cbmc/proofs/TCP/prvTCPHandleState/TCPHandleState_harness.c b/test/cbmc/proofs/TCP/prvTCPHandleState/TCPHandleState_harness.c index 1f5f99ea68..fddf816a3c 100644 --- a/test/cbmc/proofs/TCP/prvTCPHandleState/TCPHandleState_harness.c +++ b/test/cbmc/proofs/TCP/prvTCPHandleState/TCPHandleState_harness.c @@ -35,7 +35,8 @@ #include "FreeRTOS_IP_Private.h" #include "FreeRTOS_TCP_IP.h" -#include "../../utility/memory_assignments.c" +/* CBMC includes. */ +#include "cbmc.h" extern FreeRTOS_Socket_t * xSocketToListen; @@ -61,32 +62,211 @@ TaskHandle_t xTaskGetCurrentTaskHandle( void ) BaseType_t publicTCPHandleState( FreeRTOS_Socket_t * pxSocket, NetworkBufferDescriptor_t ** ppxNetworkBuffer ); +void * vSocketClose( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL." ); + + return NULL; +} + +void vSocketWakeUpUser( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL." ); + + return NULL; +} + +/* Memory assignment for FreeRTOS_Socket_t */ +FreeRTOS_Socket_t * ensure_FreeRTOS_Socket_t_is_allocated() +{ + size_t buf_size; /* Give buffer_size an unconstrained value */ + FreeRTOS_Socket_t * pxSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) ); + + __CPROVER_assume( pxSocket != NULL ); + pxSocket->u.xTCP.rxStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.txStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.pxPeerSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) ); + pxSocket->pxEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); + pxSocket->u.xTCP.pxAckMessage = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + + if( pxSocket->u.xTCP.pxAckMessage != NULL ) + { + __CPROVER_assume( ( buf_size > ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + sizeof( TCPHeader_t ) ) ) && ( buf_size < ipconfigNETWORK_MTU ) ); + pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer = safeMalloc( buf_size ); + __CPROVER_assume( pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer != NULL ); + } + + return pxSocket; +} + +/* lTCPAddRxdata is proven separately. */ +int32_t lTCPAddRxdata( FreeRTOS_Socket_t * pxSocket, + size_t uxOffset, + const uint8_t * pcData, + uint32_t ulByteCount ) +{ + return nondet_int32(); +} + +/* prvSendData is proven separately. */ +BaseType_t prvSendData( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t ** ppxNetworkBuffer, + uint32_t ulReceiveLength, + BaseType_t xByteCount ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( *ppxNetworkBuffer != NULL, "*ppxNetworkBuffer cannot be NULL" ); + + return nondet_BaseType(); +} + +/* prvTCPPrepareSend is proven separately. */ +int32_t prvTCPPrepareSend( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t ** ppxNetworkBuffer, + UBaseType_t uxOptionsLength ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( *ppxNetworkBuffer != NULL, "*ppxNetworkBuffer cannot be NULL" ); + + return nondet_int32(); +} + +/* Mock all window APIs */ +int32_t lTCPWindowRxCheck( TCPWindow_t * pxWindow, + uint32_t ulSequenceNumber, + uint32_t ulLength, + uint32_t ulSpace, + uint32_t * pulSkipCount ) +{ + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxWindow, sizeof( TCPWindow_t ) ), "pxWindow must be readable" ); + *pulSkipCount = nondet_uint32(); + + return nondet_int32(); +} + +uint32_t ulTCPWindowTxAck( TCPWindow_t * pxWindow, + uint32_t ulSequenceNumber ) +{ + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxWindow, sizeof( TCPWindow_t ) ), "pxWindow must be readable" ); + + return nondet_uint32(); +} + +void vTCPWindowInit( TCPWindow_t * pxWindow, + uint32_t ulAckNumber, + uint32_t ulSequenceNumber, + uint32_t ulMSS ) +{ + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxWindow, sizeof( TCPWindow_t ) ), "pxWindow must be readable" ); +} + +BaseType_t xTCPWindowRxEmpty( const TCPWindow_t * pxWindow ) +{ + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxWindow, sizeof( TCPWindow_t ) ), "pxWindow must be readable" ); + + return nondet_BaseType(); +} + +BaseType_t xTCPWindowTxDone( const TCPWindow_t * pxWindow ) +{ + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxWindow, sizeof( TCPWindow_t ) ), "pxWindow must be readable" ); + + return nondet_BaseType(); +} + +/* Mock all stream buffer APIs */ +size_t uxStreamBufferGet( StreamBuffer_t * const pxBuffer, + size_t uxOffset, + uint8_t * const pucData, + size_t uxMaxCount, + BaseType_t xPeek ) +{ + __CPROVER_assert( pxBuffer != NULL, "pxBuffer cannot be NULL" ); + + return nondet_sizet(); +} + +size_t uxStreamBufferGetSpace( const StreamBuffer_t * const pxBuffer ) +{ + __CPROVER_assert( pxBuffer != NULL, "pxBuffer cannot be NULL" ); + + return nondet_sizet(); +} + +/* Mock all transmission APIs. */ +UBaseType_t prvSetOptions( FreeRTOS_Socket_t * pxSocket, + const NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( pxNetworkBuffer != NULL, "pxNetworkBuffer cannot be NULL" ); + + return nondet_ubasetype(); +} + +UBaseType_t prvSetSynAckOptions( FreeRTOS_Socket_t * pxSocket, + TCPHeader_t * pxTCPHeader ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( pxTCPHeader != NULL, "pxTCPHeader cannot be NULL" ); + + return nondet_ubasetype(); +} + +void prvTCPAddTxData( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); +} + +BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, "pxNetworkBuffer cannot be NULL" ); + + return nondet_BaseType(); +} + +const char * FreeRTOS_inet_ntop( BaseType_t xAddressFamily, + const void * pvSource, + char * pcDestination, + socklen_t uxSize ) +{ + __CPROVER_assert( __CPROVER_r_ok( pcDestination, uxSize ), "input buffer must be available" ); + + __CPROVER_assert( ( xAddressFamily == FREERTOS_AF_INET6 && __CPROVER_r_ok( pvSource, 16 ) ) || + ( xAddressFamily == FREERTOS_AF_INET && __CPROVER_r_ok( pvSource, 4 ) ), + "input address must be available" ); +} + void harness() { FreeRTOS_Socket_t * pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); - size_t socketSize = sizeof( FreeRTOS_Socket_t ); - if( ensure_memory_is_valid( pxSocket, socketSize ) ) + __CPROVER_assume( pxSocket != NULL ); + + /* ucOptionLength is the number of valid bytes in ulOptionsData[]. + * ulOptionsData[] is initialized as uint32_t ulOptionsData[ipSIZE_TCP_OPTIONS/sizeof(uint32_t)]. + * This assumption is required for a memcpy function that copies uxOptionsLength + * data from pxTCPHeader->ucOptdata to pxTCPWindow->ulOptionsData.*/ + __CPROVER_assume( pxSocket->u.xTCP.xTCPWindow.ucOptionLength == sizeof( uint32_t ) * ipSIZE_TCP_OPTIONS / sizeof( uint32_t ) ); + /* uxRxWinSize is initialized as size_t. This assumption is required to terminate `while(uxWinSize > 0xfffful)` loop.*/ + __CPROVER_assume( pxSocket->u.xTCP.uxRxWinSize >= 0 && pxSocket->u.xTCP.uxRxWinSize <= sizeof( size_t ) ); + /* uxRxWinSize is initialized as uint16_t. This assumption is required to terminate `while(uxWinSize > 0xfffful)` loop.*/ + __CPROVER_assume( pxSocket->u.xTCP.usMSS == sizeof( uint16_t ) ); + /* ucPeerWinScaleFactor is limited in range [0,14]. */ + __CPROVER_assume( pxSocket->u.xTCP.ucPeerWinScaleFactor <= tcpTCP_OPT_WSOPT_MAXIMUM_VALUE ); + + if( xIsCallingFromIPTask() == pdFALSE ) { - /* ucOptionLength is the number of valid bytes in ulOptionsData[]. - * ulOptionsData[] is initialized as uint32_t ulOptionsData[ipSIZE_TCP_OPTIONS/sizeof(uint32_t)]. - * This assumption is required for a memcpy function that copies uxOptionsLength - * data from pxTCPHeader->ucOptdata to pxTCPWindow->ulOptionsData.*/ - __CPROVER_assume( pxSocket->u.xTCP.xTCPWindow.ucOptionLength == sizeof( uint32_t ) * ipSIZE_TCP_OPTIONS / sizeof( uint32_t ) ); - /* uxRxWinSize is initialized as size_t. This assumption is required to terminate `while(uxWinSize > 0xfffful)` loop.*/ - __CPROVER_assume( pxSocket->u.xTCP.uxRxWinSize >= 0 && pxSocket->u.xTCP.uxRxWinSize <= sizeof( size_t ) ); - /* uxRxWinSize is initialized as uint16_t. This assumption is required to terminate `while(uxWinSize > 0xfffful)` loop.*/ - __CPROVER_assume( pxSocket->u.xTCP.usMSS == sizeof( uint16_t ) ); - - if( xIsCallingFromIPTask() == pdFALSE ) - { - __CPROVER_assume( pxSocket->u.xTCP.bits.bPassQueued == pdFALSE_UNSIGNED ); - __CPROVER_assume( pxSocket->u.xTCP.bits.bPassAccept == pdFALSE_UNSIGNED ); - } + __CPROVER_assume( pxSocket->u.xTCP.bits.bPassQueued == pdFALSE_UNSIGNED ); + __CPROVER_assume( pxSocket->u.xTCP.bits.bPassAccept == pdFALSE_UNSIGNED ); } - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); - size_t bufferSize = sizeof( NetworkBufferDescriptor_t ); + NetworkBufferDescriptor_t * pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + __CPROVER_assume( pxNetworkBuffer != NULL ); FreeRTOS_Socket_t xSck; xSocketToListen = &xSck; @@ -94,17 +274,16 @@ void harness() /* Call to init the socket list. */ vListInitialise( &xBoundTCPSocketsList ); - if( ensure_memory_is_valid( pxNetworkBuffer, bufferSize ) ) - { - /* Allocates min. buffer size required for the proof */ - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( sizeof( TCPPacket_t ) + uxIPHeaderSizeSocket( pxSocket ) ); - } + /* Allocates min. buffer size required for the proof */ + pxNetworkBuffer->pucEthernetBuffer = safeMalloc( sizeof( TCPPacket_t ) + uxIPHeaderSizeSocket( pxSocket ) ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + pxNetworkBuffer->xDataLength = sizeof( TCPPacket_t ) + uxIPHeaderSizeSocket( pxSocket ); - if( ensure_memory_is_valid( pxSocket, socketSize ) && - ensure_memory_is_valid( pxNetworkBuffer, bufferSize ) && - ensure_memory_is_valid( pxNetworkBuffer->pucEthernetBuffer, sizeof( TCPPacket_t ) ) && - ensure_memory_is_valid( pxSocket->u.xTCP.pxPeerSocket, socketSize ) ) + if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE ) { - publicTCPHandleState( pxSocket, &pxNetworkBuffer ); + /* Make sure we have parent socket if reuse is set to FALSE to avoid assertion in vTCPStateChange(). */ + __CPROVER_assume( pxSocket->u.xTCP.pxPeerSocket != NULL ); } + + publicTCPHandleState( pxSocket, &pxNetworkBuffer ); } diff --git a/test/cbmc/proofs/TCP/prvTCPPrepareSend/Makefile.json b/test/cbmc/proofs/TCP/prvTCPPrepareSend/Makefile.json index df1df0a680..e1dd2fdf05 100644 --- a/test/cbmc/proofs/TCP/prvTCPPrepareSend/Makefile.json +++ b/test/cbmc/proofs/TCP/prvTCPPrepareSend/Makefile.json @@ -40,7 +40,10 @@ "$(FREERTOS_PLUS_TCP)/test/FreeRTOS-Kernel/list.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "OPT": [ @@ -48,7 +51,8 @@ ], "DEF": [ - "FREERTOS_TCP_ENABLE_VERIFICATION" + "FREERTOS_TCP_ENABLE_VERIFICATION", + "CBMC_REQUIRE_NETWORKBUFFER_ETHERNETBUFFER_NONNULL" ], "INC": [ diff --git a/test/cbmc/proofs/TCP/prvTCPPrepareSend/TCPPrepareSend_harness.c b/test/cbmc/proofs/TCP/prvTCPPrepareSend/TCPPrepareSend_harness.c index d889e16382..63bfac2799 100644 --- a/test/cbmc/proofs/TCP/prvTCPPrepareSend/TCPPrepareSend_harness.c +++ b/test/cbmc/proofs/TCP/prvTCPPrepareSend/TCPPrepareSend_harness.c @@ -36,30 +36,35 @@ #include "FreeRTOS_TCP_IP.h" #include "FreeRTOS_Stream_Buffer.h" -#include "../../utility/memory_assignments.c" +/* CBMC includes. */ +#include "cbmc.h" /* This proof assumes that pxGetNetworkBufferWithDescriptor is implemented correctly. */ int32_t publicTCPPrepareSend( FreeRTOS_Socket_t * pxSocket, NetworkBufferDescriptor_t ** ppxNetworkBuffer, UBaseType_t uxOptionsLength ); -/* Abstraction of pxGetNetworkBufferWithDescriptor. It creates a buffer. */ -NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, - TickType_t xBlockTimeTicks ) +/* Memory assignment for FreeRTOS_Socket_t */ +FreeRTOS_Socket_t * ensure_FreeRTOS_Socket_t_is_allocated() { - NetworkBufferDescriptor_t * pxBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); - size_t bufferSize = sizeof( NetworkBufferDescriptor_t ); + size_t buf_size; /* Give buffer_size an unconstrained value */ + FreeRTOS_Socket_t * pxSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) + sizeof( IPTCPSocket_t ) ); - if( ensure_memory_is_valid( pxBuffer, bufferSize ) ) + __CPROVER_assume( pxSocket != NULL ); + pxSocket->u.xTCP.rxStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.txStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.pxPeerSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) ); + pxSocket->pxEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); + pxSocket->u.xTCP.pxAckMessage = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + + if( pxSocket->u.xTCP.pxAckMessage != NULL ) { - /* The code does not expect pucEthernetBuffer to be equal to NULL if - * pxBuffer is not NULL. */ - pxBuffer->pucEthernetBuffer = malloc( xRequestedSizeBytes ); - __CPROVER_assume( pxBuffer->pucEthernetBuffer != NULL ); - pxBuffer->xDataLength = xRequestedSizeBytes; + __CPROVER_assume( ( buf_size > ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + sizeof( TCPHeader_t ) ) ) && ( buf_size < ipconfigNETWORK_MTU ) ); + pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer = safeMalloc( buf_size ); + __CPROVER_assume( pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer != NULL ); } - return pxBuffer; + return pxSocket; } /* Get rid of configASSERT in FreeRTOS_TCP_IP.c */ @@ -68,37 +73,94 @@ BaseType_t xIsCallingFromIPTask( void ) return pdTRUE; } -void harness() +/* Mock FreeRTOS_TCP_State_Handling.h APIs */ +BaseType_t prvTCPSocketIsActive( eIPTCPState_t eStatus ) +{ + return nondet_BaseType(); +} + +/* Mock FreeRTOS_TCP_WIN.h APIs */ +BaseType_t xTCPWindowTxDone( const TCPWindow_t * pxWindow ) { - FreeRTOS_Socket_t * pxSocket = malloc( sizeof( FreeRTOS_Socket_t ) ); + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + return nondet_uint32(); +} - __CPROVER_assume( pxSocket != NULL ); - pxSocket->u.xTCP.rxStream = malloc( sizeof( StreamBuffer_t ) ); - pxSocket->u.xTCP.txStream = malloc( sizeof( StreamBuffer_t ) ); - pxSocket->u.xTCP.pxPeerSocket = malloc( sizeof( FreeRTOS_Socket_t ) ); +uint32_t ulTCPWindowTxGet( TCPWindow_t * pxWindow, + uint32_t ulWindowSize, + int32_t * plPosition ) +{ + uint32_t ulReturn = nondet_uint32(); + + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + __CPROVER_assert( plPosition != NULL, "plPosition cannot be NULL" ); + + /* This function returns the data length of next sending window, which is never larger than network MTU. */ + __CPROVER_assume( ulReturn < ipconfigNETWORK_MTU ); + return ulReturn; +} + +/* Mock FreeRTOS_Stream_Buffers.h APIs */ +size_t uxStreamBufferDistance( const StreamBuffer_t * const pxBuffer, + size_t uxLower, + size_t uxUpper ) +{ + __CPROVER_assert( pxBuffer != NULL, "pxBuffer cannot be NULL" ); + return nondet_sizet(); +} + +size_t uxStreamBufferGet( StreamBuffer_t * const pxBuffer, + size_t uxOffset, + uint8_t * const pucData, + size_t uxMaxCount, + BaseType_t xPeek ) +{ + __CPROVER_assert( pxBuffer != NULL, "pxBuffer cannot be NULL" ); + return nondet_sizet(); +} + +void * vSocketClose( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL." ); + + return NULL; +} + +void vSocketWakeUpUser( FreeRTOS_Socket_t * pxSocket ) +{ + __CPROVER_assert( pxSocket != NULL, "Closing socket cannot be NULL." ); - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); + return NULL; +} + +void harness() +{ + NetworkBufferDescriptor_t * pxNetworkBuffer; + FreeRTOS_Socket_t * pxSocket; size_t socketSize = sizeof( FreeRTOS_Socket_t ); /* Allocates min. buffer size required for the proof */ - size_t bufferSize = sizeof( TCPPacket_t ) + uxIPHeaderSizeSocket( pxSocket ); + size_t bufferSize; - if( ensure_memory_is_valid( pxNetworkBuffer, sizeof( *pxNetworkBuffer ) ) ) - { - pxNetworkBuffer->xDataLength = bufferSize; + pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); + __CPROVER_assume( pxSocket != NULL ); - /* The code does not expect pucEthernetBuffer to be equal to NULL if - * pxNetworkBuffer is not NULL. */ - pxNetworkBuffer->pucEthernetBuffer = malloc( bufferSize ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE ) + { + /* Make sure we have parent socket if reuse is set to FALSE to avoid assertion in vTCPStateChange(). */ + __CPROVER_assume( pxSocket->u.xTCP.pxPeerSocket != NULL ); } - UBaseType_t uxOptionsLength; + bufferSize = sizeof( TCPPacket_t ) + ipSIZE_OF_IPv6_HEADER; + + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( bufferSize, 0 ); + __CPROVER_assume( pxNetworkBuffer != NULL ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); /* Call to init the socket list. */ vListInitialise( &xBoundTCPSocketsList ); if( pxSocket ) { - publicTCPPrepareSend( pxSocket, &pxNetworkBuffer, uxOptionsLength ); + publicTCPPrepareSend( pxSocket, &pxNetworkBuffer, 0 ); } } diff --git a/test/cbmc/proofs/TCP/prvTCPReturnPacket/Makefile.json b/test/cbmc/proofs/TCP/prvTCPReturnPacket/Makefile.json index 1b67f5a076..12a17ef309 100644 --- a/test/cbmc/proofs/TCP/prvTCPReturnPacket/Makefile.json +++ b/test/cbmc/proofs/TCP/prvTCPReturnPacket/Makefile.json @@ -39,14 +39,19 @@ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Stream_Buffer.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission_IPv4.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "DEF": [ "ipconfigUSE_LINKED_RX_MESSAGES={RX_MESSAGES}", - "FREERTOS_TCP_ENABLE_VERIFICATION" + "FREERTOS_TCP_ENABLE_VERIFICATION", + "CBMC_REQUIRE_NETWORKBUFFER_ETHERNETBUFFER_NONNULL" ], "INC": [ diff --git a/test/cbmc/proofs/TCP/prvTCPReturnPacket/TCPReturnPacket_harness.c b/test/cbmc/proofs/TCP/prvTCPReturnPacket/TCPReturnPacket_harness.c index 786d10cfd2..9f03585c39 100644 --- a/test/cbmc/proofs/TCP/prvTCPReturnPacket/TCPReturnPacket_harness.c +++ b/test/cbmc/proofs/TCP/prvTCPReturnPacket/TCPReturnPacket_harness.c @@ -37,10 +37,42 @@ #include "FreeRTOS_TCP_IP.h" #include "FreeRTOS_TCP_Transmission.h" -#include "../../utility/memory_assignments.c" - +/* CBMC includes */ #include "cbmc.h" +/* prvTCPReturnPacket_IPV6 is proven separately. */ +void prvTCPReturnPacket_IPV6( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t * pxDescriptor, + uint32_t ulLen, + BaseType_t xReleaseAfterSend ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( pxDescriptor != NULL, "pxDescriptor cannot be NULL" ); +} + +/* Memory assignment for FreeRTOS_Socket_t */ +FreeRTOS_Socket_t * ensure_FreeRTOS_Socket_t_is_allocated() +{ + size_t buf_size; /* Give buffer_size an unconstrained value */ + FreeRTOS_Socket_t * pxSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) + sizeof( IPTCPSocket_t ) ); + + __CPROVER_assume( pxSocket != NULL ); + pxSocket->u.xTCP.rxStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.txStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.pxPeerSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) ); + pxSocket->pxEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); + pxSocket->u.xTCP.pxAckMessage = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + + if( pxSocket->u.xTCP.pxAckMessage != NULL ) + { + __CPROVER_assume( ( buf_size > ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + sizeof( TCPHeader_t ) ) ) && ( buf_size < ipconfigNETWORK_MTU ) ); + pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer = safeMalloc( buf_size ); + __CPROVER_assume( pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer != NULL ); + } + + return pxSocket; +} + /* * This function is implemented by a third party. * After looking through a couple of samples in the demos folder, it seems @@ -89,27 +121,31 @@ void prvTCPReturn_SetEndPoint( const FreeRTOS_Socket_t * pxSocket, NetworkBufferDescriptor_t * pxDuplicateNetworkBufferWithDescriptor( const NetworkBufferDescriptor_t * const pxNetworkBuffer, size_t xNewLength ) { - NetworkBufferDescriptor_t * pxNetworkBuffer = safeMalloc( xNewLength ); + NetworkBufferDescriptor_t * pxLocalNetworkBuffer; + EthernetHeader_t * pxHeader; + + pxLocalNetworkBuffer = pxGetNetworkBufferWithDescriptor( xNewLength, 0 ); - if( ensure_memory_is_valid( pxNetworkBuffer, xNewLength ) ) + if( pxLocalNetworkBuffer != NULL ) { - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( sizeof( TCPPacket_t ) ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer ); + /* In this test case, we only focus on IPv4. */ + pxHeader = ( ( const EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxHeader->usFrameType != ipIPv6_FRAME_TYPE ); /* Add an end point to the network buffer present. Its assumed that the * network interface layer correctly assigns the end point to the generated buffer. */ - pxNetworkBuffer->pxEndPoint = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); - __CPROVER_assume( pxNetworkBuffer->pxEndPoint != NULL ); - pxNetworkBuffer->pxEndPoint->pxNext = NULL; + pxLocalNetworkBuffer->pxEndPoint = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); + __CPROVER_assume( pxLocalNetworkBuffer->pxEndPoint != NULL ); + pxLocalNetworkBuffer->pxEndPoint->pxNext = NULL; /* Add an interface */ - pxNetworkBuffer->pxEndPoint->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); - __CPROVER_assume( pxNetworkBuffer->pxEndPoint->pxNetworkInterface != NULL ); + pxLocalNetworkBuffer->pxEndPoint->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); + __CPROVER_assume( pxLocalNetworkBuffer->pxEndPoint->pxNetworkInterface != NULL ); - pxNetworkBuffer->pxEndPoint->pxNetworkInterface->pfOutput = NetworkInterfaceOutputFunction_Stub; + pxLocalNetworkBuffer->pxEndPoint->pxNetworkInterface->pfOutput = NetworkInterfaceOutputFunction_Stub; } - return pxNetworkBuffer; + return pxLocalNetworkBuffer; } uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, @@ -169,29 +205,40 @@ eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress, void harness() { - FreeRTOS_Socket_t * pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); + FreeRTOS_Socket_t * pxSocket; + NetworkBufferDescriptor_t * pxNetworkBuffer; BaseType_t xReleaseAfterSend; uint32_t ulLen; + EthernetHeader_t * pxHeader; + + pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); + + if( pxSocket != NULL ) + { + /* In this test case, we only focus on IPv4. */ + __CPROVER_assume( pxSocket->bits.bIsIPv6 == pdFALSE_UNSIGNED ); + } + + __CPROVER_assume( ( ulLen >= sizeof( TCPPacket_t ) ) && ( ulLen < ipconfigNETWORK_MTU - ipSIZE_OF_ETH_HEADER ) ); + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ulLen + ipSIZE_OF_ETH_HEADER, 0 ); /* The code does not expect both of these to be equal to NULL at the same time. */ __CPROVER_assume( pxSocket != NULL || pxNetworkBuffer != NULL ); + /* ucPeerWinScaleFactor is limited in range [0,14]. */ + __CPROVER_assume( pxSocket->u.xTCP.ucMyWinScaleFactor <= tcpTCP_OPT_WSOPT_MAXIMUM_VALUE ); /* If network buffer is properly created. */ - if( ensure_memory_is_valid( pxNetworkBuffer, sizeof( *pxNetworkBuffer ) ) ) + if( pxNetworkBuffer != NULL ) { - /* Assume that the length is proper. */ - __CPROVER_assume( ( ulLen >= sizeof( TCPPacket_t ) ) && ( ulLen < ipconfigNETWORK_MTU ) ); - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( ulLen + ipSIZE_OF_ETH_HEADER ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer ); - - pxNetworkBuffer->xDataLength = ( size_t ) ulLen; + /* In this test case, we only focus on IPv4. */ + pxHeader = ( ( const EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxHeader->usFrameType != ipIPv6_FRAME_TYPE ); /* Add an end point to the network buffer present. Its assumed that the * network interface layer correctly assigns the end point to the generated buffer. */ pxNetworkBuffer->pxEndPoint = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); - if( ensure_memory_is_valid( pxNetworkBuffer->pxEndPoint, sizeof( NetworkEndPoint_t ) ) ) + if( pxNetworkBuffer->pxEndPoint != NULL ) { /* Add an interface */ pxNetworkBuffer->pxEndPoint->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); diff --git a/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/Makefile.json b/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/Makefile.json index 9b28c3b345..629ef713d4 100644 --- a/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/Makefile.json +++ b/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/Makefile.json @@ -11,14 +11,19 @@ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_Stream_Buffer.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission_IPv6.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto" + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto" ], "DEF": [ "ipconfigUSE_LINKED_RX_MESSAGES={RX_MESSAGES}", - "FREERTOS_TCP_ENABLE_VERIFICATION" + "FREERTOS_TCP_ENABLE_VERIFICATION", + "CBMC_REQUIRE_NETWORKBUFFER_ETHERNETBUFFER_NONNULL" ], "INC": [ diff --git a/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/TCPReturnPacket_IPv6_harness.c b/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/TCPReturnPacket_IPv6_harness.c index ea2e87b2fd..d768af7c38 100644 --- a/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/TCPReturnPacket_IPv6_harness.c +++ b/test/cbmc/proofs/TCP/prvTCPReturnPacket_IPv6/TCPReturnPacket_IPv6_harness.c @@ -35,10 +35,9 @@ #include "FreeRTOS_IP_Private.h" #include "FreeRTOS_TCP_IP.h" #include "FreeRTOS_TCP_Transmission.h" +#include "FreeRTOS_ND.h" /* CBMC includes. */ -#include "../../utility/memory_assignments.c" - #include "cbmc.h" /* @@ -64,6 +63,51 @@ BaseType_t NetworkInterfaceOutputFunction_Stub( struct xNetworkInterface * pxDes return 0; } +/* Memory assignment for FreeRTOS_Socket_t */ +FreeRTOS_Socket_t * ensure_FreeRTOS_Socket_t_is_allocated() +{ + size_t buf_size; /* Give buffer_size an unconstrained value */ + FreeRTOS_Socket_t * pxSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) + sizeof( IPTCPSocket_t ) ); + + __CPROVER_assume( pxSocket != NULL ); + pxSocket->u.xTCP.rxStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.txStream = safeMalloc( sizeof( StreamBuffer_t ) ); + pxSocket->u.xTCP.pxPeerSocket = safeMalloc( sizeof( FreeRTOS_Socket_t ) ); + pxSocket->pxEndPoint = safeMalloc( sizeof( NetworkEndPoint_t ) ); + pxSocket->u.xTCP.pxAckMessage = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + + if( pxSocket->u.xTCP.pxAckMessage != NULL ) + { + __CPROVER_assume( ( buf_size > ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + sizeof( TCPHeader_t ) ) ) && ( buf_size < ipconfigNETWORK_MTU ) ); + pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer = safeMalloc( buf_size ); + __CPROVER_assume( pxSocket->u.xTCP.pxAckMessage->pucEthernetBuffer != NULL ); + } + + return pxSocket; +} + +void prvTCPReturnPacket_IPV4( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t * pxDescriptor, + uint32_t ulLen, + BaseType_t xReleaseAfterSend ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( pxDescriptor != NULL, "pxDescriptor cannot be NULL" ); +} + +/* Abstraction of eNDGetCacheEntry. */ +eARPLookupResult_t eNDGetCacheEntry( IPv6_Address_t * pxIPAddress, + MACAddress_t * const pxMACAddress, + struct xNetworkEndPoint ** ppxEndPoint ) +{ + eARPLookupResult_t xReturn; + + __CPROVER_assert( __CPROVER_r_ok( pxIPAddress, sizeof( IPv6_Address_t ) ), "pxIPAddress must be readable" ); + __CPROVER_assert( __CPROVER_w_ok( pxMACAddress, sizeof( MACAddress_t ) ), "pxMACAddress must be writeable" ); + + return xReturn; +} + /* Abstraction of this functions creates an endpoint and assign it to network interface * endpoint, real endpoint doesn't matter in this test. */ void prvTCPReturn_SetEndPoint( const FreeRTOS_Socket_t * pxSocket, @@ -87,27 +131,31 @@ void prvTCPReturn_SetEndPoint( const FreeRTOS_Socket_t * pxSocket, NetworkBufferDescriptor_t * pxDuplicateNetworkBufferWithDescriptor( const NetworkBufferDescriptor_t * const pxNetworkBuffer, size_t xNewLength ) { - NetworkBufferDescriptor_t * pxNetworkBuffer = safeMalloc( xNewLength ); + NetworkBufferDescriptor_t * pxLocalNetworkBuffer; + EthernetHeader_t * pxHeader; + + pxLocalNetworkBuffer = pxGetNetworkBufferWithDescriptor( xNewLength, 0 ); - if( ensure_memory_is_valid( pxNetworkBuffer, xNewLength ) ) + if( pxLocalNetworkBuffer != NULL ) { - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( sizeof( TCPPacket_t ) ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer ); + /* In this test case, we only focus on IPv6. */ + pxHeader = ( ( const EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxHeader->usFrameType == ipIPv6_FRAME_TYPE ); /* Add an end point to the network buffer present. Its assumed that the * network interface layer correctly assigns the end point to the generated buffer. */ - pxNetworkBuffer->pxEndPoint = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); - __CPROVER_assume( pxNetworkBuffer->pxEndPoint != NULL ); - pxNetworkBuffer->pxEndPoint->pxNext = NULL; + pxLocalNetworkBuffer->pxEndPoint = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); + __CPROVER_assume( pxLocalNetworkBuffer->pxEndPoint != NULL ); + pxLocalNetworkBuffer->pxEndPoint->pxNext = NULL; /* Add an interface */ - pxNetworkBuffer->pxEndPoint->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); - __CPROVER_assume( pxNetworkBuffer->pxEndPoint->pxNetworkInterface != NULL ); + pxLocalNetworkBuffer->pxEndPoint->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); + __CPROVER_assume( pxLocalNetworkBuffer->pxEndPoint->pxNetworkInterface != NULL ); - pxNetworkBuffer->pxEndPoint->pxNetworkInterface->pfOutput = NetworkInterfaceOutputFunction_Stub; + pxLocalNetworkBuffer->pxEndPoint->pxNetworkInterface->pfOutput = NetworkInterfaceOutputFunction_Stub; } - return pxNetworkBuffer; + return pxLocalNetworkBuffer; } uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, @@ -136,29 +184,40 @@ uint16_t usGenerateChecksum( uint16_t usSum, void harness() { - FreeRTOS_Socket_t * pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); - NetworkBufferDescriptor_t * pxNetworkBuffer = ensure_FreeRTOS_NetworkBuffer_is_allocated(); + FreeRTOS_Socket_t * pxSocket; + NetworkBufferDescriptor_t * pxNetworkBuffer; BaseType_t xReleaseAfterSend; uint32_t ulLen; + EthernetHeader_t * pxHeader; + + pxSocket = ensure_FreeRTOS_Socket_t_is_allocated(); + + if( pxSocket != NULL ) + { + /* In this test case, we only focus on IPv6. */ + __CPROVER_assume( pxSocket->bits.bIsIPv6 != pdFALSE_UNSIGNED ); + } + + __CPROVER_assume( ( ulLen >= sizeof( TCPPacket_IPv6_t ) ) && ( ulLen < ipconfigNETWORK_MTU - ipSIZE_OF_ETH_HEADER ) ); + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ulLen + ipSIZE_OF_ETH_HEADER, 0 ); /* The code does not expect both of these to be equal to NULL at the same time. */ __CPROVER_assume( pxSocket != NULL || pxNetworkBuffer != NULL ); + /* ucPeerWinScaleFactor is limited in range [0,14]. */ + __CPROVER_assume( pxSocket->u.xTCP.ucMyWinScaleFactor <= tcpTCP_OPT_WSOPT_MAXIMUM_VALUE ); /* If network buffer is properly created. */ - if( ensure_memory_is_valid( pxNetworkBuffer, sizeof( *pxNetworkBuffer ) ) ) + if( pxNetworkBuffer != NULL ) { - /* Assume that the length is proper. */ - __CPROVER_assume( ( ulLen >= sizeof( TCPPacket_IPv6_t ) ) && ( ulLen < ipconfigNETWORK_MTU ) ); - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( ulLen + ipSIZE_OF_ETH_HEADER ); - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); - - pxNetworkBuffer->xDataLength = ( size_t ) ( ulLen + ipSIZE_OF_ETH_HEADER ); + /* In this test case, we only focus on IPv6. */ + pxHeader = ( ( const EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxHeader->usFrameType == ipIPv6_FRAME_TYPE ); /* Add an end point to the network buffer present. Its assumed that the * network interface layer correctly assigns the end point to the generated buffer. */ pxNetworkBuffer->pxEndPoint = ( NetworkEndPoint_t * ) safeMalloc( sizeof( NetworkEndPoint_t ) ); - if( ensure_memory_is_valid( pxNetworkBuffer->pxEndPoint, sizeof( NetworkEndPoint_t ) ) ) + if( pxNetworkBuffer->pxEndPoint != NULL ) { /* Add an interface */ pxNetworkBuffer->pxEndPoint->pxNetworkInterface = ( NetworkInterface_t * ) safeMalloc( sizeof( NetworkInterface_t ) ); diff --git a/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/Makefile.json b/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/Makefile.json index f7ef2a84df..b5abd6f010 100644 --- a/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/Makefile.json +++ b/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/Makefile.json @@ -2,6 +2,9 @@ "ENTRY": "vProcessGeneratedUDPPacket", "CBMCFLAGS": [ + "--unwind 1", + "--unwindset FreeRTOS_InterfaceEndPointOnNetMask.0:3", + "--nondet-static" ], "OBJS": [ diff --git a/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/vProcessGeneratedUDPPacket_harness.c b/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/vProcessGeneratedUDPPacket_harness.c index b56bc475bd..5d8239d8a4 100644 --- a/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/vProcessGeneratedUDPPacket_harness.c +++ b/test/cbmc/proofs/UDP/vProcessGeneratedUDPPacket/vProcessGeneratedUDPPacket_harness.c @@ -19,6 +19,12 @@ #include "memory_assignments.c" #include "freertos_api.c" +/* vProcessGeneratedUDPPacket_IPv6 is proven separately. */ +void vProcessGeneratedUDPPacket_IPv6( NetworkBufferDescriptor_t * const pxNetworkBuffer ) +{ + __CPROVER_assert( pxNetworkBuffer != NULL, "pxNetworkBuffer cannot be NULL" ); +} + /* We do not need to calculate the actual checksum for the proof to be complete. * Neither does the checksum matter for completeness. */ uint16_t usGenerateChecksum( uint16_t usSum, @@ -33,7 +39,6 @@ uint16_t usGenerateChecksum( uint16_t usSum, return usChecksum; } - /* We do not need to calculate the actual checksum for the proof to be complete. * Neither does the checksum matter for completeness. */ uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, diff --git a/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c b/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c index a1c0c80b03..e8c498ac9f 100644 --- a/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c +++ b/test/cbmc/proofs/parsing/ProcessIPPacket/ProcessIPPacket_harness.c @@ -9,9 +9,97 @@ /* CBMC includes. */ #include "cbmc.h" +NetworkEndPoint_t xEndpoint; + eFrameProcessingResult_t __CPROVER_file_local_FreeRTOS_IP_c_prvProcessIPPacket( const IPPacket_t * pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer ); +/* Check if input is a valid extension header ID. */ +BaseType_t xIsExtensionHeader( uint8_t ucCurrentHeader ) +{ + BaseType_t xReturn = pdFALSE; + + switch( ucCurrentHeader ) + { + case ipIPv6_EXT_HEADER_HOP_BY_HOP: + case ipIPv6_EXT_HEADER_DESTINATION_OPTIONS: + case ipIPv6_EXT_HEADER_ROUTING_HEADER: + case ipIPv6_EXT_HEADER_FRAGMENT_HEADER: + case ipIPv6_EXT_HEADER_AUTHEN_HEADER: + case ipIPv6_EXT_HEADER_SECURE_PAYLOAD: + case ipIPv6_EXT_HEADER_MOBILITY_HEADER: + xReturn = pdTRUE; + break; + } + + return xReturn; +} + +/* Abstraction of xGetExtensionOrder. To ensure the result of prepared extension headers is same. */ +BaseType_t xGetExtensionOrder( uint8_t ucProtocol, + uint8_t ucNextHeader ) +{ + return xIsExtensionHeader( ucProtocol ); +} + +BaseType_t xCheckRequiresARPResolution( const NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + BaseType_t xReturn; + + __CPROVER_assert( pxNetworkBuffer != NULL, "pxNetworkBuffer cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength ), "Data in pxNetworkBuffer must be readable" ); +} + +void vARPRefreshCacheEntryAge( const MACAddress_t * pxMACAddress, + const uint32_t ulIPAddress ) +{ + __CPROVER_assert( pxMACAddress != NULL, "pxMACAddress cannot be NULL" ); +} + +void vNDRefreshCacheEntry( const MACAddress_t * pxMACAddress, + const IPv6_Address_t * pxIPAddress, + NetworkEndPoint_t * pxEndPoint ) +{ + __CPROVER_assert( pxMACAddress != NULL, "pxMACAddress cannot be NULL" ); + __CPROVER_assert( pxIPAddress != NULL, "pxIPAddress cannot be NULL" ); + __CPROVER_assert( pxEndPoint != NULL, "pxEndPoint cannot be NULL" ); +} + +NetworkEndPoint_t * FreeRTOS_FindEndPointOnIP_IPv4( uint32_t ulIPAddress, + uint32_t ulWhere ) +{ + NetworkEndPoint_t * pxEndpoint = NULL; + + if( nondet_bool() ) + { + pxEndpoint = pxNetworkEndPoints; + } + + return pxEndpoint; +} + +/* proof is done separately */ +eFrameProcessingResult_t ProcessICMPPacket( const NetworkBufferDescriptor_t * const pxNetworkBuffer ) +{ + eFrameProcessingResult_t xReturn; + + __CPROVER_assert( pxNetworkBuffer != NULL, "pxEndPoint cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength ), "Data in pxNetworkBuffer must be readable" ); + + return xReturn; +} + +/* proof is done separately */ +eFrameProcessingResult_t prvProcessICMPMessage_IPv6( NetworkBufferDescriptor_t * const pxNetworkBuffer ) +{ + eFrameProcessingResult_t xReturn; + + __CPROVER_assert( pxNetworkBuffer != NULL, "pxEndPoint cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength ), "Data in pxNetworkBuffer must be readable" ); + + return xReturn; +} + /* proof is done separately */ BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t * pxNetworkBuffer ) { @@ -67,6 +155,7 @@ void harness() { NetworkBufferDescriptor_t * const pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); uint8_t * pucEthernetBuffer = ( uint8_t * ) safeMalloc( ipTOTAL_ETHERNET_FRAME_SIZE + ipIP_TYPE_OFFSET ); + EthernetHeader_t * pxHeader; __CPROVER_assume( pxNetworkBuffer != NULL ); __CPROVER_assume( pucEthernetBuffer != NULL ); @@ -83,7 +172,10 @@ void harness() __CPROVER_assume( pxNetworkEndPoints != NULL ); __CPROVER_assume( pxNetworkEndPoints->pxNext == NULL ); - IPPacket_t * const pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; + /* In this test case, we only focus on IPv4. */ + pxHeader = ( ( const EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxHeader->usFrameType != ipIPv6_FRAME_TYPE ); + IPPacket_t * const pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer; __CPROVER_file_local_FreeRTOS_IP_c_prvProcessIPPacket( pxIPPacket, pxNetworkBuffer ); } diff --git a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/Makefile.json b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/Makefile.json index f2643c9b98..bb142d42a4 100644 --- a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/Makefile.json +++ b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/Makefile.json @@ -10,6 +10,8 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Utils.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IP_Timers.goto", @@ -23,16 +25,11 @@ ], "INSTFLAGS": [ - "--remove-function-body prvSingleStepTCPHeaderOptions", - "--remove-function-body prvCheckOptions", - "--remove-function-body prvTCPPrepareSend", - "--remove-function-body prvTCPReturnPacket", - "--remove-function-body prvTCPHandleState", - "--remove-function-body vTCPStateChange" ], "DEF": [ - "FREERTOS_TCP_ENABLE_VERIFICATION" + "FREERTOS_TCP_ENABLE_VERIFICATION", + "CBMC_GETNETWORKBUFFER_FAILURE_BOUND" ], "INC": [ diff --git a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/ProcessReceivedTCPPacket_harness.c b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/ProcessReceivedTCPPacket_harness.c index 00f6e8014c..d60cdd6bc9 100644 --- a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/ProcessReceivedTCPPacket_harness.c +++ b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket/ProcessReceivedTCPPacket_harness.c @@ -35,6 +35,83 @@ TaskHandle_t xTaskGetCurrentTaskHandle( void ) return pxCurrentTCB; } +/* Abstraction of vTCPStateChange */ +void vTCPStateChange( FreeRTOS_Socket_t * pxSocket, + enum eTCP_STATE eTCPState ) +{ +} + +/* prvTCPReturnPacket is proven separately */ +void prvTCPReturnPacket( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t * pxDescriptor, + uint32_t ulLen, + BaseType_t xReleaseAfterSend ) +{ + __CPROVER_assert( pxSocket != NULL || pxDescriptor != NULL, "Either pxSocket or pxDescriptor must be non-NULL" ); + __CPROVER_assert( pxDescriptor->pucEthernetBuffer != NULL, "pucEthernetBuffer should not be NULL" ); +} + +/* prvTCPPrepareSend is proven separately. */ +int32_t prvTCPPrepareSend( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t ** ppxNetworkBuffer, + UBaseType_t uxOptionsLength ) +{ + int32_t ret = nondet_int32(); + + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( *ppxNetworkBuffer != NULL, "*ppxNetworkBuffer cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( ( *ppxNetworkBuffer )->pucEthernetBuffer, ( *ppxNetworkBuffer )->xDataLength ), "Data in *ppxNetworkBuffer must be readable" ); + + __CPROVER_assume( ret >= 0 && ret <= ipconfigNETWORK_MTU ); + return ret; +} + +/* prvTCPHandleState is proven separately. */ +BaseType_t prvTCPHandleState( FreeRTOS_Socket_t * pxSocket, + NetworkBufferDescriptor_t ** ppxNetworkBuffer ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( *ppxNetworkBuffer != NULL, "*ppxNetworkBuffer cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( ( *ppxNetworkBuffer )->pucEthernetBuffer, ( *ppxNetworkBuffer )->xDataLength ), "Data in *ppxNetworkBuffer must be readable" ); + + return nondet_basetype(); +} + +/* prvCheckOptions is proven separately. */ +BaseType_t prvCheckOptions( FreeRTOS_Socket_t * pxSocket, + const NetworkBufferDescriptor_t * pxNetworkBuffer ) +{ + __CPROVER_assert( pxSocket != NULL, "pxSocket cannot be NULL" ); + __CPROVER_assert( pxNetworkBuffer != NULL, "*ppxNetworkBuffer cannot be NULL" ); + __CPROVER_assert( __CPROVER_r_ok( pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength ), "Data in *ppxNetworkBuffer must be readable" ); + + return nondet_basetype(); +} + +BaseType_t xTCPWindowTxHasData( TCPWindow_t const * pxWindow, + uint32_t ulWindowSize, + TickType_t * pulDelay ) +{ + __CPROVER_assert( pxWindow != NULL, "pxWindow cannot be NULL" ); + __CPROVER_assert( pulDelay != NULL, "pulDelay cannot be NULL" ); + + return nondet_basetype(); +} + +/* Abstraction of xSequenceLessThan */ +BaseType_t xSequenceLessThan( uint32_t a, + uint32_t b ) +{ + return nondet_basetype(); +} + +/* Abstraction of xSequenceGreaterThan */ +BaseType_t xSequenceGreaterThan( uint32_t a, + uint32_t b ) +{ + return nondet_basetype(); +} + /* Abstraction of prvHandleListen_IPV4 */ FreeRTOS_Socket_t * prvHandleListen_IPV4( FreeRTOS_Socket_t * pxSocket, NetworkBufferDescriptor_t * pxNetworkBuffer ) @@ -62,6 +139,7 @@ FreeRTOS_Socket_t * pxTCPSocketLookup( uint32_t ulLocalIP, { /* This test case is for IPv4. */ __CPROVER_assume( xRetSocket->bits.bIsIPv6 == pdFALSE ); + __CPROVER_assume( xRetSocket->u.xTCP.ucPeerWinScaleFactor <= tcpTCP_OPT_WSOPT_MAXIMUM_VALUE ); } return xRetSocket; @@ -76,7 +154,7 @@ NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedS if( pxNetworkBuffer ) { pxNetworkBuffer->pucEthernetBuffer = safeMalloc( xRequestedSizeBytes ); - __CPROVER_assume( pxNetworkBuffer->xDataLength == ipSIZE_OF_ETH_HEADER + sizeof( int32_t ) ); + pxNetworkBuffer->xDataLength = xRequestedSizeBytes; } return pxNetworkBuffer; @@ -98,14 +176,16 @@ size_t uxIPHeaderSizeSocket( const FreeRTOS_Socket_t * pxSocket ) void harness() { - NetworkBufferDescriptor_t * pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + NetworkBufferDescriptor_t * pxNetworkBuffer; + size_t tcpPacketSize; - /* To avoid asserting on the network buffer being NULL. */ - __CPROVER_assume( pxNetworkBuffer != NULL ); + __CPROVER_assume( tcpPacketSize >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + sizeof( TCPHeader_t ) ) ); + + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( tcpPacketSize, 0 ); - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( sizeof( TCPPacket_t ) ); - /* To avoid asserting on the ethernet buffer being NULL. */ + /* To avoid asserting on the network buffer being NULL. */ + __CPROVER_assume( pxNetworkBuffer != NULL ); __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); xProcessReceivedTCPPacket( pxNetworkBuffer ); diff --git a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/Makefile.json b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/Makefile.json index 53a28f7332..c37bc279d3 100644 --- a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/Makefile.json +++ b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/Makefile.json @@ -10,23 +10,17 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP_IPv6.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission.goto", - "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_Transmission_IPv6.goto" + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_TCP_IP.goto" ], "INSTFLAGS": [ - "--remove-function-body prvSingleStepTCPHeaderOptions", - "--remove-function-body prvCheckOptions", - "--remove-function-body prvTCPPrepareSend", - "--remove-function-body prvTCPReturnPacket", - "--remove-function-body prvTCPHandleState", - "--remove-function-body vTCPStateChange" ], "DEF": [ - "FREERTOS_TCP_ENABLE_VERIFICATION" + "FREERTOS_TCP_ENABLE_VERIFICATION", + "CBMC_GETNETWORKBUFFER_FAILURE_BOUND" ], "INC": [ diff --git a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/ProcessReceivedTCPPacket_IPv6_harness.c b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/ProcessReceivedTCPPacket_IPv6_harness.c index c2be060cee..204d404e44 100644 --- a/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/ProcessReceivedTCPPacket_IPv6_harness.c +++ b/test/cbmc/proofs/parsing/ProcessReceivedTCPPacket_IPv6/ProcessReceivedTCPPacket_IPv6_harness.c @@ -63,6 +63,7 @@ FreeRTOS_Socket_t * pxTCPSocketLookup( uint32_t ulLocalIP, { /* This test case is for IPv6. */ __CPROVER_assume( xRetSocket->bits.bIsIPv6 == pdTRUE ); + __CPROVER_assume( xRetSocket->u.xTCP.ucPeerWinScaleFactor <= tcpTCP_OPT_WSOPT_MAXIMUM_VALUE ); } return xRetSocket; @@ -99,20 +100,21 @@ size_t uxIPHeaderSizeSocket( const FreeRTOS_Socket_t * pxSocket ) void harness() { - NetworkBufferDescriptor_t * pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); + NetworkBufferDescriptor_t * pxNetworkBuffer; EthernetHeader_t * pxEthernetHeader; + size_t tcpPacketSize; - /* To avoid asserting on the network buffer being NULL. */ - __CPROVER_assume( pxNetworkBuffer != NULL ); + __CPROVER_assume( tcpPacketSize >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + sizeof( TCPHeader_t ) ) ); - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( sizeof( TCPPacket_IPv6_t ) ); + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( tcpPacketSize, 0 ); /* To avoid asserting on the ethernet buffer being NULL. */ + __CPROVER_assume( pxNetworkBuffer != NULL ); __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); - /* Ethernet frame type is checked before calling xProcessReceivedTCPPacket_IPV6. */ + /* In this test case, we focus on IPv6 packets. */ pxEthernetHeader = ( EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer; __CPROVER_assume( pxEthernetHeader->usFrameType == ipIPv6_FRAME_TYPE ); - xProcessReceivedTCPPacket_IPV6( pxNetworkBuffer ); + xProcessReceivedTCPPacket( pxNetworkBuffer ); } diff --git a/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/Makefile.json b/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/Makefile.json index bc0bc61db1..8c6859f4b8 100644 --- a/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/Makefile.json +++ b/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/Makefile.json @@ -11,6 +11,8 @@ "OBJS": [ "$(ENTRY)_harness.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_api.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/freertos_kernel_api.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_UDP_IP.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_UDP_IPv4.goto", diff --git a/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/ProcessReceivedUDPPacket_harness.c b/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/ProcessReceivedUDPPacket_harness.c index 6d282aca97..0b2b8c14c5 100644 --- a/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/ProcessReceivedUDPPacket_harness.c +++ b/test/cbmc/proofs/parsing/ProcessReceivedUDPPacket/ProcessReceivedUDPPacket_harness.c @@ -9,6 +9,9 @@ #include "FreeRTOS_UDP_IP.h" #include "FreeRTOS_TCP_IP.h" +/* CBMC includes. */ +#include "cbmc.h" + /*This proof assumes that pxUDPSocketLookup is implemented correctly. */ /* This proof was done before. Hence we assume it to be correct here. */ @@ -17,6 +20,12 @@ void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, { } +void vARPRefreshCacheEntryAge( const MACAddress_t * pxMACAddress, + const uint32_t ulIPAddress ) +{ + __CPROVER_assert( pxMACAddress != NULL, "pxMACAddress cannot be NULL" ); +} + /* This proof was done before. Hence we assume it to be correct here. */ BaseType_t xIsDHCPSocket( Socket_t xSocket ) { @@ -68,19 +77,6 @@ BaseType_t xProcessReceivedUDPPacket_IPv6( NetworkBufferDescriptor_t * pxNetwork return xReturn; } -/* Implementation of safe malloc */ -void * safeMalloc( size_t xWantedSize ) -{ - if( xWantedSize == 0 ) - { - return NULL; - } - - uint8_t byte; - - return byte ? malloc( xWantedSize ) : NULL; -} - /* Abstraction of pxUDPSocketLookup */ FreeRTOS_Socket_t * pxUDPSocketLookup( UBaseType_t uxLocalPort ) { @@ -89,26 +85,23 @@ FreeRTOS_Socket_t * pxUDPSocketLookup( UBaseType_t uxLocalPort ) void harness() { - NetworkBufferDescriptor_t * pxNetworkBuffer = safeMalloc( sizeof( NetworkBufferDescriptor_t ) ); - BaseType_t * pxIsWaitingForARPResolution; + NetworkBufferDescriptor_t * pxNetworkBuffer; + BaseType_t xIsWaitingForARPResolution; NetworkEndPoint_t xEndpoint; uint16_t usPort; + EthernetHeader_t * pxHeader; - pxIsWaitingForARPResolution = safeMalloc( sizeof( BaseType_t ) ); - - /* The function under test is only called by the IP-task. The below pointer is an - * address of a local variable which is being passed to the function under test. - * Thus, it cannot ever be NULL. */ - __CPROVER_assume( pxIsWaitingForARPResolution != NULL ); - + pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( UDPPacket_t ), 0 ); /* The network buffer must not be NULL, checked in prvProcessEthernetPacket. */ __CPROVER_assume( pxNetworkBuffer != NULL ); + __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); - pxNetworkBuffer->pucEthernetBuffer = safeMalloc( sizeof( UDPPacket_t ) ); pxNetworkBuffer->pxEndPoint = &xEndpoint; - /* The ethernet buffer must be valid. */ - __CPROVER_assume( pxNetworkBuffer->pucEthernetBuffer != NULL ); + /* In this test case, we only focus on IPv4. */ + pxHeader = ( ( const EthernetHeader_t * ) pxNetworkBuffer->pucEthernetBuffer ); + __CPROVER_assume( pxHeader->usFrameType != ipIPv6_FRAME_TYPE ); - xProcessReceivedUDPPacket( pxNetworkBuffer, usPort, pxIsWaitingForARPResolution ); + xIsWaitingForARPResolution = nondet_BaseType(); + xProcessReceivedUDPPacket( pxNetworkBuffer, usPort, &xIsWaitingForARPResolution ); } diff --git a/test/cbmc/proofs/prvChecksumIPv6Checks/Makefile.json b/test/cbmc/proofs/prvChecksumIPv6Checks/Makefile.json index 9645ee00a4..7d84cfceee 100644 --- a/test/cbmc/proofs/prvChecksumIPv6Checks/Makefile.json +++ b/test/cbmc/proofs/prvChecksumIPv6Checks/Makefile.json @@ -13,6 +13,7 @@ [ "$(ENTRY)_harness.goto", "$(FREERTOS_PLUS_TCP)/test/cbmc/stubs/cbmc.goto", + "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IPv6.goto", "$(FREERTOS_PLUS_TCP)/source/FreeRTOS_IPv6_Utils.goto" ], "INSTFLAGS": diff --git a/test/cbmc/proofs/run-cbmc-proofs.py b/test/cbmc/proofs/run-cbmc-proofs.py index 429d787342..af7bad7ca0 100755 --- a/test/cbmc/proofs/run-cbmc-proofs.py +++ b/test/cbmc/proofs/run-cbmc-proofs.py @@ -186,7 +186,7 @@ def add_proof_jobs(proof_directory, proof_root): # Run 3 CBMC tasks - cbmc_out = str(proof_directory / "cbmc.txt") + cbmc_out = str(proof_directory / "cbmc.xml") run_cmd([ "litani", "add-job", "--command", "make cbmc", @@ -301,12 +301,12 @@ def main(): if not args.no_standalone: run_build(args.parallel_jobs) - out_sym = pathlib.Path("/tmp")/"litani"/"runs"/"latest" - out_dir = out_sym.resolve() + out_sym = pathlib.Path("/tmp")/"litani"/"runs"/"latest" + out_dir = out_sym.resolve() - local_copy = pathlib.Path("output")/"latest" - local_copy.parent.mkdir(exist_ok=True) - local_copy.symlink_to(out_dir) + local_copy = pathlib.Path("output")/"latest" + local_copy.parent.mkdir(exist_ok=True) + local_copy.symlink_to(out_dir) if __name__ == "__main__": diff --git a/test/cbmc/stubs/freertos_api.c b/test/cbmc/stubs/freertos_api.c index d541aa07a7..7534c34b8a 100644 --- a/test/cbmc/stubs/freertos_api.c +++ b/test/cbmc/stubs/freertos_api.c @@ -49,6 +49,21 @@ Socket_t FreeRTOS_socket( BaseType_t xDomain, } } +/**************************************************************** +* Abstract FreeRTOS_socket. +* https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/API/socket.html +* +* We stub out this function to do nothing but allocate space for a +* socket containing unconstrained data or return an error. +****************************************************************/ + +BaseType_t FreeRTOS_listen( Socket_t xSocket, + BaseType_t xBacklog ) +{ + __CPROVER_assert( xSocket != NULL, "Socket cannot be NULL" ); + return nondet_BaseType(); +} + /**************************************************************** * Abstract FreeRTOS_setsockopt. * https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/API/setsockopt.html @@ -185,7 +200,7 @@ int32_t FreeRTOS_sendto( Socket_t xSocket, /**************************************************************** * Abstract FreeRTOS_GetUDPPayloadBuffer -* https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/FreeRTOS_GetUDPPayloadBuffer.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/34-FreeRTOS_GetUDPPayloadBuffer * * We stub out this function to do nothing but allocate a buffer of * unconstrained size containing unconstrained data and return a @@ -314,7 +329,7 @@ void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNet /**************************************************************** * Abstract FreeRTOS_GetAddressConfiguration -* https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/API/FreeRTOS_GetAddressConfiguration.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/32-FreeRTOS_GetAddressConfiguration ****************************************************************/ void FreeRTOS_GetAddressConfiguration( uint32_t * pulIPAddress, @@ -374,7 +389,6 @@ const char * pcApplicationHostnameHook( void ) /**************************************************************** * Abstract xNetworkInterfaceOutput -* https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Porting.html#xNetworkInterfaceOutput ****************************************************************/ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend ) @@ -388,3 +402,42 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkB } /****************************************************************/ + +/**************************************************************** +* Abstract vIPSetARPResolutionTimerEnableState +****************************************************************/ +void vIPSetARPResolutionTimerEnableState( BaseType_t xEnableState ) +{ +} + +/****************************************************************/ + +/**************************************************************** +* Abstract vIPSetARPResolutionTimerEnableState +****************************************************************/ +BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber ) +{ + __CPROVER_assert( pulNumber != NULL, "The input number cannot be NULL" ); + + BaseType_t xReturn; + + *pulNumber = nondet_uint32(); + + /* Return some random value. */ + return xReturn; +} + +/****************************************************************/ + +/**************************************************************** +* Abstract vIPSetARPResolutionTimerEnableState +****************************************************************/ +uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress, + uint16_t usSourcePort, + uint32_t ulDestinationAddress, + uint16_t usDestinationPort ) +{ + return nondet_uint32(); +} + +/****************************************************************/ diff --git a/test/cbmc/stubs/freertos_kernel_api.c b/test/cbmc/stubs/freertos_kernel_api.c index b74b4ec09c..79fd0ff822 100644 --- a/test/cbmc/stubs/freertos_kernel_api.c +++ b/test/cbmc/stubs/freertos_kernel_api.c @@ -80,3 +80,91 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, } /****************************************************************/ + +/**************************************************************** +* Abstract xEventGroupSetBits +****************************************************************/ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ +} + +/****************************************************************/ + +/**************************************************************** +* Abstract xEventGroupSetBits +****************************************************************/ +EventGroupHandle_t xEventGroupCreate( void ) +{ + EventGroupHandle_t xReturn; + + return xReturn; +} + +/****************************************************************/ + +/**************************************************************** +* Abstract xQueueGenericSend +****************************************************************/ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, + const void * const pvItemToQueue, + TickType_t xTicksToWait, + const BaseType_t xCopyPosition ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + +/****************************************************************/ + +/**************************************************************** +* Abstract uxQueueMessagesWaiting +****************************************************************/ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) +{ + UBaseType_t uxReturn; + + __CPROVER_assume( uxReturn <= 2 ); + + return uxReturn; +} + +/****************************************************************/ + +/**************************************************************** +* Abstract vTaskSetTimeOutState +****************************************************************/ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ +} + +/****************************************************************/ + +/**************************************************************** +* Abstract xTaskCheckForTimeOut +****************************************************************/ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, + TickType_t * const pxTicksToWait ) +{ + BaseType_t xReturn; + + __CPROVER_assume( ( xReturn == pdTRUE ) || ( xReturn == pdFALSE ) ); + + return xReturn; +} + +/****************************************************************/ + +/**************************************************************** +* Abstract xTaskGetTickCount +****************************************************************/ +TickType_t xTaskGetTickCount( void ) +{ + TickType_t xReturn; + + return xReturn; +} + +/****************************************************************/ diff --git a/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h b/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h index 63c54c297d..906205d1de 100644 --- a/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h +++ b/test/unit-test/ConfigFiles/FreeRTOSIPConfig.h @@ -109,7 +109,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/ConfigFiles/pack_struct_end.h b/test/unit-test/ConfigFiles/pack_struct_end.h index 1331692969..c9e312645f 100644 --- a/test/unit-test/ConfigFiles/pack_struct_end.h +++ b/test/unit-test/ConfigFiles/pack_struct_end.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ __attribute__( ( packed ) ); diff --git a/test/unit-test/ConfigFiles/pack_struct_start.h b/test/unit-test/ConfigFiles/pack_struct_start.h index 59ca8f40f3..1a319a66ed 100644 --- a/test/unit-test/ConfigFiles/pack_struct_start.h +++ b/test/unit-test/ConfigFiles/pack_struct_start.h @@ -28,7 +28,7 @@ /***************************************************************************** * * See the following URL for an explanation of this file: -* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html +* https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/10-Porting/02-Embedded_Compiler_Porting * *****************************************************************************/ diff --git a/test/unit-test/FreeRTOS_ARP_DataLenLessThanMinPacket/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_ARP_DataLenLessThanMinPacket/FreeRTOSIPConfig.h index a201bb85ab..645b4ec3fb 100644 --- a/test/unit-test/FreeRTOS_ARP_DataLenLessThanMinPacket/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_ARP_DataLenLessThanMinPacket/FreeRTOSIPConfig.h @@ -103,7 +103,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_DHCPv6/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_DHCPv6/FreeRTOSIPConfig.h index 6ef75fdc66..6e3e053d39 100644 --- a/test/unit-test/FreeRTOS_DHCPv6/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_DHCPv6/FreeRTOSIPConfig.h @@ -107,7 +107,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_DHCPv6/FreeRTOS_DHCPv6_utest.c b/test/unit-test/FreeRTOS_DHCPv6/FreeRTOS_DHCPv6_utest.c index e8cbc34cea..9a673bd7e4 100644 --- a/test/unit-test/FreeRTOS_DHCPv6/FreeRTOS_DHCPv6_utest.c +++ b/test/unit-test/FreeRTOS_DHCPv6/FreeRTOS_DHCPv6_utest.c @@ -729,6 +729,34 @@ static void prvPrepareAdvertiseNoServerID() prvAddOptionPreference( pdFALSE ); } +/** + * @brief Prepare buffer content as DHCPv6 advertise with extra option value 32. + */ +static void prvPrepareAdvertiseExtraOptionValue32() +{ + /* We hard code the option sequence in advertise message. + * 1. Client ID + * 2. Server ID + * 3. IA_NA + * - Sub-option IA Address + * - Sub-option IA Prefix + * - Sub-option Status Code + * 4. Status Code + * 5. Preference + * 6. Extra Option 32 + */ + uint16_t usVal; + + prvPrepareAdvertise(); + /* Add extra option with value 32. */ + usVal = 32; + vAddBitOperation( eTestDHCPv6BitOperationRead16, &usVal, 2, "ExtraOption32" ); + usVal = 2U; + vAddBitOperation( eTestDHCPv6BitOperationRead16, &usVal, 2, "ExtraOption32Length" ); + usVal = 0U; + vAddBitOperation( eTestDHCPv6BitOperationReadCustom, &usVal, 2, "ExtraOptionStatusValue" ); +} + /** * @brief Prepare buffer content as DHCPv6 advertise. */ @@ -2046,6 +2074,54 @@ void test_vDHCPv6Process_prvDHCPv6Analyse_LackServerID() TEST_ASSERT_EQUAL( eWaitingOffer, xEndPoint.xDHCPData.eDHCPState ); } +/** + * @brief Check if vDHCPv6Process can skip setting bit map when the option value is 32. + */ +void test_vDHCPv6Process_prvDHCPv6Analyse_ExtraOptionValue32() +{ + NetworkEndPoint_t xEndPoint; + DHCPMessage_IPv6_t xDHCPMessage; + struct xSOCKET xLocalDHCPv6Socket; + + memset( &xEndPoint, 0, sizeof( NetworkEndPoint_t ) ); + memset( &xLocalDHCPv6Socket, 0, sizeof( struct xSOCKET ) ); + memset( &xDHCPMessage, 0, sizeof( DHCPMessage_IPv6_t ) ); + + pxNetworkEndPoints = &xEndPoint; + + memcpy( xEndPoint.xMACAddress.ucBytes, ucDefaultMACAddress, sizeof( ucDefaultMACAddress ) ); + memcpy( xEndPoint.ipv6_settings.xPrefix.ucBytes, &xDefaultNetPrefix.ucBytes, sizeof( IPv6_Address_t ) ); + xEndPoint.ipv6_settings.uxPrefixLength = 64; + xEndPoint.bits.bIPv6 = pdTRUE; + xEndPoint.bits.bWantDHCP = pdTRUE; + + xEndPoint.xDHCPData.eDHCPState = eWaitingOffer; + xEndPoint.xDHCPData.eExpectedState = eWaitingOffer; + xEndPoint.xDHCPData.ulTransactionId = TEST_DHCPV6_TRANSACTION_ID; + xEndPoint.xDHCPData.xDHCPSocket = &xLocalDHCPv6Socket; + memcpy( xEndPoint.xDHCPData.ucClientDUID, ucTestDHCPv6OptionClientID, sizeof( ucTestDHCPv6OptionClientID ) ); + + xEndPoint.pxDHCPMessage = &xDHCPMessage; + + FreeRTOS_recvfrom_IgnoreAndReturn( 150 ); + FreeRTOS_recvfrom_IgnoreAndReturn( 0 ); + xTaskGetTickCount_IgnoreAndReturn( 0 ); + + prvPrepareAdvertiseExtraOptionValue32(); + + xApplicationGetRandomNumber_Stub( xStubxApplicationGetRandomNumber ); + FreeRTOS_inet_pton6_IgnoreAndReturn( pdTRUE ); + FreeRTOS_sendto_IgnoreAndReturn( 0 ); + + prvPrepareRequest(); + + vDHCPv6Process( pdFALSE, &xEndPoint ); + + /* The endpoint receives the DHCPv6 Advertise message from DHCPv6 server. + * Then change the state to eWaitingAcknowledge. */ + TEST_ASSERT_EQUAL( eWaitingAcknowledge, xEndPoint.xDHCPData.eDHCPState ); +} + /** * @brief Check if vDHCPv6Process can drop packets while failing on initialization of bit configuration. */ diff --git a/test/unit-test/FreeRTOS_DNS/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_DNS/FreeRTOSIPConfig.h index c11bb29789..b9c0a2db31 100644 --- a/test/unit-test/FreeRTOS_DNS/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_DNS/FreeRTOSIPConfig.h @@ -108,7 +108,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_DNS_ConfigNoCallback/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_DNS_ConfigNoCallback/FreeRTOSIPConfig.h index 5db6747e20..b7b76cd81b 100644 --- a/test/unit-test/FreeRTOS_DNS_ConfigNoCallback/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_DNS_ConfigNoCallback/FreeRTOSIPConfig.h @@ -108,7 +108,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOSIPConfig.h index 7d70702c58..3939f82653 100644 --- a/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOSIPConfig.h @@ -107,7 +107,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c b/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c index 20b6dcb6b6..7513a97683 100644 --- a/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c +++ b/test/unit-test/FreeRTOS_DNS_Parser/FreeRTOS_DNS_Parser_utest.c @@ -997,7 +997,7 @@ void test_DNS_TreatNBNS_Fail_BufferAllocation1( void ) usChar2u16_ExpectAnyArgsAndReturn( dnsNBNS_TYPE_NET_BIOS ); /* usType */ usChar2u16_ExpectAnyArgsAndReturn( dnsNBNS_FLAGS_OPCODE_QUERY ); - catch_assert( DNS_TreatNBNS( pucPayload, uxBufferLength, 1234 ) ); + DNS_TreatNBNS( pucPayload, uxBufferLength, 1234 ); ASSERT_DNS_QUERY_HOOK_CALLED(); } @@ -2855,6 +2855,275 @@ void test_DNS_ParseDNSReply_answer_lmmnr_reply_valid_new_netbuffer3( void ) ASSERT_DNS_QUERY_HOOK_CALLED(); } +/** + * @brief ensures that when the re-use network buffer is reused when xBufferAllocFixedSize + * is set, then packet is sent over the network. + */ +void test_DNS_ParseDNSReply_answer_lmmnr_reply_valid_fixed_buffer( void ) +{ + uint32_t ret; + uint8_t udp_buffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ] = { 0 }; + uint8_t * pucUDPPayloadBuffer = ( ( uint8_t * ) udp_buffer ) + ipUDP_PAYLOAD_OFFSET_IPv4; + size_t uxBufferLength = 250; + struct freertos_addrinfo * pxAddressInfo; + uint16_t usPort = 80; + NetworkEndPoint_t xEndPoint = { 0 }; + + memset( pucUDPPayloadBuffer, 0x00, uxBufferLength ); + + xBufferAllocFixedSize = pdTRUE; + + NetworkBufferDescriptor_t pxNetworkBuffer = { 0 }; + xEndPoint.ipv4_settings.ulIPAddress = 0xABCD1234; + pxNetworkBuffer.pucEthernetBuffer = udp_buffer; + pxNetworkBuffer.xDataLength = uxBufferLength; + pxNetworkBuffer.pxEndPoint = &xEndPoint; + + UDPPacket_t * pxUDPPacket; + IPHeader_t * pxIPHeader; + UDPHeader_t * pxUDPHeader; + + pxUDPPacket = ( ( UDPPacket_t * ) + pxNetworkBuffer.pucEthernetBuffer ); + pxIPHeader = &pxUDPPacket->xIPHeader; + pxIPHeader->ucVersionHeaderLength = 0x0; + pxUDPHeader = &pxUDPPacket->xUDPHeader; + IPPacket_t * xIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer.pucEthernetBuffer ); + + pxIPHeader->ulSourceIPAddress = 1234; + + NetworkBufferDescriptor_t pxNewBuffer; + pxNewBuffer.pucEthernetBuffer = udp_buffer; + pxNewBuffer.xDataLength = uxBufferLength; + + BaseType_t xExpected = pdFALSE; + size_t beg = sizeof( DNSMessage_t ); + + DNSMessage_t * dns_header; + + dns_header = ( DNSMessage_t * ) pucUDPPayloadBuffer; + + dns_header->usQuestions = FreeRTOS_htons( 1 ); + dns_header->usAnswers = FreeRTOS_htons( 2 ); + dns_header->usFlags = dnsDNS_PORT; + + pucUDPPayloadBuffer[ beg ] = 38; + beg++; + strcpy( pucUDPPayloadBuffer + beg, "FreeRTOSbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ); + beg += 38; + + beg += sizeof( uint32_t ); + + pucUDPPayloadBuffer[ beg ] = 38; + beg++; + strcpy( pucUDPPayloadBuffer + beg, "FreeRTOSbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ); + beg += 38; + + pucUDPPayloadBuffer[ beg ] = 38; + beg++; + strcpy( pucUDPPayloadBuffer + beg, "FreeRTOSbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" ); + beg += 38; + + uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER ); + usChar2u16_ExpectAnyArgsAndReturn( dnsTYPE_AAAA_HOST ); /* usType */ + usChar2u16_ExpectAnyArgsAndReturn( dnsCLASS_IN ); /* usClass */ + hook_return = pdTRUE; + pxUDPPayloadBuffer_to_NetworkBuffer_ExpectAnyArgsAndReturn( &pxNetworkBuffer ); + + usGenerateChecksum_ExpectAnyArgsAndReturn( 555 ); + usGenerateProtocolChecksum_ExpectAnyArgsAndReturn( 444 ); + vReturnEthernetFrame_Expect( &pxNetworkBuffer, pdFALSE ); + + ret = DNS_ParseDNSReply( pucUDPPayloadBuffer, + uxBufferLength, + &pxAddressInfo, + xExpected, + usPort ); + + TEST_ASSERT_EQUAL( pdFALSE, ret ); + ASSERT_DNS_QUERY_HOOK_CALLED(); +} + +/** + * @brief ensures that when the re-use network buffer is reused when xBufferAllocFixedSize + * is set, but packet is not sent over the network due to buffer overflow. + */ +void test_DNS_ParseDNSReply_answer_lmmnr_reply_fixed_buffer_full_content( void ) +{ + uint32_t ret; + uint8_t udp_buffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ] = { 0 }; + uint8_t * pucUDPPayloadBuffer = ( ( uint8_t * ) udp_buffer ) + ipUDP_PAYLOAD_OFFSET_IPv4; + /* Maximum UDP payload length is 1500 + 14 - 42 = 1472. */ + size_t uxBufferLength = ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER - ipUDP_PAYLOAD_OFFSET_IPv4; + struct freertos_addrinfo * pxAddressInfo; + uint16_t usPort = 80; + NetworkEndPoint_t xEndPoint = { 0 }; + int i; + + memset( pucUDPPayloadBuffer, 0x00, uxBufferLength ); + + xBufferAllocFixedSize = pdTRUE; + + NetworkBufferDescriptor_t pxNetworkBuffer = { 0 }; + xEndPoint.ipv4_settings.ulIPAddress = 0xABCD1234; + pxNetworkBuffer.pucEthernetBuffer = udp_buffer; + pxNetworkBuffer.xDataLength = uxBufferLength; + pxNetworkBuffer.pxEndPoint = &xEndPoint; + + UDPPacket_t * pxUDPPacket; + IPHeader_t * pxIPHeader; + UDPHeader_t * pxUDPHeader; + + pxUDPPacket = ( ( UDPPacket_t * ) + pxNetworkBuffer.pucEthernetBuffer ); + pxIPHeader = &pxUDPPacket->xIPHeader; + pxIPHeader->ucVersionHeaderLength = 0x0; + pxUDPHeader = &pxUDPPacket->xUDPHeader; + IPPacket_t * xIPPacket = ( ( IPPacket_t * ) pxNetworkBuffer.pucEthernetBuffer ); + + pxIPHeader->ulSourceIPAddress = 1234; + + NetworkBufferDescriptor_t pxNewBuffer; + pxNewBuffer.pucEthernetBuffer = udp_buffer; + pxNewBuffer.xDataLength = uxBufferLength; + + BaseType_t xExpected = pdFALSE; + size_t beg = sizeof( DNSMessage_t ); + + DNSMessage_t * dns_header; + + dns_header = ( DNSMessage_t * ) pucUDPPayloadBuffer; + + dns_header->usQuestions = FreeRTOS_htons( 6 ); + dns_header->usAnswers = FreeRTOS_htons( 0 ); + dns_header->usFlags = dnsDNS_PORT; + + /* First 5 queries have maximum length. */ + + /* DNS name field format requirements: + * - First two bits must be zero to indicate real length + * - Maximum length of a single label is 63 bytes (due to first two bits requirement) + * - Total DNS name is set to 254 bytes to match ipconfigDNS_CACHE_NAME_LENGTH + * + * Format breakdown: + * [label1].[label2].[label3].[label4][\0] + * where: + * - label1, label2, label3: 63 bytes each + * - label4: 61 bytes + * - Total: 63 + 63 + 63 + 61 + 4 (length) + 1 (null terminator) = 255 bytes + */ + for( i = 0; i < 5; i++ ) + { + pucUDPPayloadBuffer[ beg ] = 63; + beg++; + strcpy( pucUDPPayloadBuffer + beg, + "FreeRTOSFreeRTOSFree" /* 20 */ + "FreeRTOSFreeRTOSFree" /* 40 */ + "FreeRTOSFreeRTOSFree" /* 60 */ + "Fre" ); /* 63 */ + beg += 63; + pucUDPPayloadBuffer[ beg ] = 63; + beg++; + strcpy( pucUDPPayloadBuffer + beg, + "FreeRTOSFreeRTOSFree" /* 20 */ + "FreeRTOSFreeRTOSFree" /* 40 */ + "FreeRTOSFreeRTOSFree" /* 60 */ + "Fre" ); /* 63 */ + beg += 63; + pucUDPPayloadBuffer[ beg ] = 63; + beg++; + strcpy( pucUDPPayloadBuffer + beg, + "FreeRTOSFreeRTOSFree" /* 20 */ + "FreeRTOSFreeRTOSFree" /* 40 */ + "FreeRTOSFreeRTOSFree" /* 60 */ + "Fre" ); /* 63 */ + beg += 63; + pucUDPPayloadBuffer[ beg ] = 61; + beg++; + strcpy( pucUDPPayloadBuffer + beg, + "FreeRTOSFreeRTOSFree" /* 20 */ + "FreeRTOSFreeRTOSFree" /* 40 */ + "FreeRTOSFreeRTOSFree" /* 60 */ + "F" ); /* 61 */ + beg += 61; + pucUDPPayloadBuffer[ beg++ ] = '\0'; + + /* Skip query's type and class. */ + beg += sizeof( uint32_t ); + } + + /* Memory layout of DNS message till here: + * - Header: 12 bytes + * - Query section: (255 + 4) * 5 bytes = 1295 bytes + * - Total used: 1307 bytes + * + * Available space in UDP payload: + * - Total UDP payload: 1472 bytes + * - Used space: 1307 bytes + * - Remaining space: 165 bytes + */ + + /* Last query to fill the remaining 165 bytes. Reserve 4 bytes for type and class fields. + * + * Format breakdown: + * [label1].[label2].[label3][\0] + * where: + * - label1, label2: 63 bytes each + * - label3: 31 bytes + * - Total: 63 + 63 + 31 + 3 (length) + 1 (null terminator) = 161 bytes */ + pucUDPPayloadBuffer[ beg ] = 63; + beg++; + strcpy( pucUDPPayloadBuffer + beg, + "FreeRTOSFreeRTOSFree" /* 20 */ + "FreeRTOSFreeRTOSFree" /* 40 */ + "FreeRTOSFreeRTOSFree" /* 60 */ + "Fre" ); /* 63 */ + beg += 63; + pucUDPPayloadBuffer[ beg ] = 63; + beg++; + strcpy( pucUDPPayloadBuffer + beg, + "FreeRTOSFreeRTOSFree" /* 20 */ + "FreeRTOSFreeRTOSFree" /* 40 */ + "FreeRTOSFreeRTOSFree" /* 60 */ + "Fre" ); /* 63 */ + beg += 63; + pucUDPPayloadBuffer[ beg ] = 31; + beg++; + strcpy( pucUDPPayloadBuffer + beg, + "FreeRTOSFreeRTOSFree" /* 20 */ + "FreeRTOSFre" ); /* 31 */ + beg += 31; + pucUDPPayloadBuffer[ beg++ ] = '\0'; + + /* Skip query's type and class. */ + beg += sizeof( uint32_t ); + + usChar2u16_ExpectAnyArgsAndReturn( dnsTYPE_AAAA_HOST ); /* usType */ + usChar2u16_ExpectAnyArgsAndReturn( dnsCLASS_IN ); /* usClass */ + usChar2u16_ExpectAnyArgsAndReturn( dnsTYPE_AAAA_HOST ); /* usType */ + usChar2u16_ExpectAnyArgsAndReturn( dnsCLASS_IN ); /* usClass */ + usChar2u16_ExpectAnyArgsAndReturn( dnsTYPE_AAAA_HOST ); /* usType */ + usChar2u16_ExpectAnyArgsAndReturn( dnsCLASS_IN ); /* usClass */ + usChar2u16_ExpectAnyArgsAndReturn( dnsTYPE_AAAA_HOST ); /* usType */ + usChar2u16_ExpectAnyArgsAndReturn( dnsCLASS_IN ); /* usClass */ + usChar2u16_ExpectAnyArgsAndReturn( dnsTYPE_AAAA_HOST ); /* usType */ + usChar2u16_ExpectAnyArgsAndReturn( dnsCLASS_IN ); /* usClass */ + usChar2u16_ExpectAnyArgsAndReturn( dnsTYPE_AAAA_HOST ); /* usType */ + usChar2u16_ExpectAnyArgsAndReturn( dnsCLASS_IN ); /* usClass */ + uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER ); + hook_return = pdTRUE; + pxUDPPayloadBuffer_to_NetworkBuffer_ExpectAnyArgsAndReturn( &pxNetworkBuffer ); + + ret = DNS_ParseDNSReply( pucUDPPayloadBuffer, + uxBufferLength, + &pxAddressInfo, + xExpected, + usPort ); + + TEST_ASSERT_EQUAL( pdFALSE, ret ); + ASSERT_DNS_QUERY_HOOK_CALLED(); +} + /** * @brief ensures that when the number of answers is zero no packet is sent over * the network diff --git a/test/unit-test/FreeRTOS_IP_DiffConfig/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IP_DiffConfig/FreeRTOSIPConfig.h index 11cd98bae9..7e5002f6a3 100644 --- a/test/unit-test/FreeRTOS_IP_DiffConfig/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IP_DiffConfig/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IP_DiffConfig1/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IP_DiffConfig1/FreeRTOSIPConfig.h index d0842b5f77..41d7f97a73 100644 --- a/test/unit-test/FreeRTOS_IP_DiffConfig1/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IP_DiffConfig1/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IP_DiffConfig2/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IP_DiffConfig2/FreeRTOSIPConfig.h index 6d99157867..46e6b10408 100644 --- a/test/unit-test/FreeRTOS_IP_DiffConfig2/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IP_DiffConfig2/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IP_DiffConfig3/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IP_DiffConfig3/FreeRTOSIPConfig.h index 7b04d1219b..37354044e5 100644 --- a/test/unit-test/FreeRTOS_IP_DiffConfig3/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IP_DiffConfig3/FreeRTOSIPConfig.h @@ -108,7 +108,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IP_Utils/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IP_Utils/FreeRTOSIPConfig.h index 9cee80e7ef..53d928f97d 100644 --- a/test/unit-test/FreeRTOS_IP_Utils/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IP_Utils/FreeRTOSIPConfig.h @@ -108,7 +108,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IP_Utils/FreeRTOS_IP_Utils_utest.c b/test/unit-test/FreeRTOS_IP_Utils/FreeRTOS_IP_Utils_utest.c index cf65a5550d..2036b4bbb1 100644 --- a/test/unit-test/FreeRTOS_IP_Utils/FreeRTOS_IP_Utils_utest.c +++ b/test/unit-test/FreeRTOS_IP_Utils/FreeRTOS_IP_Utils_utest.c @@ -2908,6 +2908,65 @@ void test_FreeRTOS_min_size_t( void ) } } +/** + * @brief test_FreeRTOS_add_int32 + * To validate FreeRTOS_add_int32. + */ +void test_FreeRTOS_add_int32( void ) +{ + int32_t lResult; + + lResult = FreeRTOS_add_int32( 1, 2 ); + TEST_ASSERT_EQUAL( 3, lResult ); + + lResult = FreeRTOS_add_int32( ipINT32_MAX_VALUE, 1 ); + TEST_ASSERT_EQUAL( ipINT32_MAX_VALUE, lResult ); + + lResult = FreeRTOS_add_int32( ipINT32_MIN_VALUE, -1 ); + TEST_ASSERT_EQUAL( ipINT32_MIN_VALUE, lResult ); + + lResult = FreeRTOS_add_int32( -1, 1 ); + TEST_ASSERT_EQUAL( 0, lResult ); +} + +/** + * @brief test_FreeRTOS_multiply_int32 + * To validate FreeRTOS_multiply_int32. + */ +void test_FreeRTOS_multiply_int32( void ) +{ + int32_t lResult; + + /* a > 0 */ + lResult = FreeRTOS_multiply_int32( ipINT32_MAX_VALUE, ipINT32_MAX_VALUE ); + TEST_ASSERT_EQUAL( ipINT32_MAX_VALUE, lResult ); + + lResult = FreeRTOS_multiply_int32( 10, ipINT32_MIN_VALUE ); + TEST_ASSERT_EQUAL( ipINT32_MIN_VALUE, lResult ); + + lResult = FreeRTOS_multiply_int32( 10, 10 ); + TEST_ASSERT_EQUAL( 100, lResult ); + + lResult = FreeRTOS_multiply_int32( 10, -1 ); + TEST_ASSERT_EQUAL( -10, lResult ); + + lResult = FreeRTOS_multiply_int32( 10, 0 ); + TEST_ASSERT_EQUAL( 0, lResult ); + + /* a <= 0 */ + lResult = FreeRTOS_multiply_int32( ipINT32_MIN_VALUE, 10 ); + TEST_ASSERT_EQUAL( ipINT32_MIN_VALUE, lResult ); + + lResult = FreeRTOS_multiply_int32( ipINT32_MIN_VALUE, ipINT32_MIN_VALUE ); + TEST_ASSERT_EQUAL( ipINT32_MAX_VALUE, lResult ); + + lResult = FreeRTOS_multiply_int32( -1, 10 ); + TEST_ASSERT_EQUAL( -10, lResult ); + + lResult = FreeRTOS_multiply_int32( -2, -2 ); + TEST_ASSERT_EQUAL( 4, lResult ); +} + /** * @brief test_FreeRTOS_round_up * To validate FreeRTOS_round_up. diff --git a/test/unit-test/FreeRTOS_IP_Utils_DiffConfig/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IP_Utils_DiffConfig/FreeRTOSIPConfig.h index 9f21c11c38..758240c37c 100644 --- a/test/unit-test/FreeRTOS_IP_Utils_DiffConfig/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IP_Utils_DiffConfig/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOSIPConfig.h index 56e8012121..696c742c53 100644 --- a/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IPv4_DiffConfig/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IPv4_DiffConfig1/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IPv4_DiffConfig1/FreeRTOSIPConfig.h index aff6bc3a38..df2e0c72bc 100644 --- a/test/unit-test/FreeRTOS_IPv4_DiffConfig1/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IPv4_DiffConfig1/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IPv6/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IPv6/FreeRTOSIPConfig.h index e4f6eb030b..bfd502529f 100644 --- a/test/unit-test/FreeRTOS_IPv6/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IPv6/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IPv6_ConfigDriverCheckChecksum/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IPv6_ConfigDriverCheckChecksum/FreeRTOSIPConfig.h index e70ec2f163..79bad30bb6 100644 --- a/test/unit-test/FreeRTOS_IPv6_ConfigDriverCheckChecksum/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IPv6_ConfigDriverCheckChecksum/FreeRTOSIPConfig.h @@ -106,7 +106,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_IPv6_Utils/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_IPv6_Utils/FreeRTOSIPConfig.h index 6e5817f753..d19467d22d 100644 --- a/test/unit-test/FreeRTOS_IPv6_Utils/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_IPv6_Utils/FreeRTOSIPConfig.h @@ -105,7 +105,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_Routing/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_Routing/FreeRTOSIPConfig.h index fe573a8b09..c908ac6a1b 100644 --- a/test/unit-test/FreeRTOS_Routing/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_Routing/FreeRTOSIPConfig.h @@ -111,7 +111,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_Routing_ConfigCompatibleWithSingle/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_Routing_ConfigCompatibleWithSingle/FreeRTOSIPConfig.h index 40d7ca68e7..a9f2db3627 100644 --- a/test/unit-test/FreeRTOS_Routing_ConfigCompatibleWithSingle/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_Routing_ConfigCompatibleWithSingle/FreeRTOSIPConfig.h @@ -115,7 +115,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_Routing_ConfigV4Only/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_Routing_ConfigV4Only/FreeRTOSIPConfig.h index 41c42c421f..4cbf12a36a 100644 --- a/test/unit-test/FreeRTOS_Routing_ConfigV4Only/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_Routing_ConfigV4Only/FreeRTOSIPConfig.h @@ -117,7 +117,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_Sockets_DiffConfig/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_Sockets_DiffConfig/FreeRTOSIPConfig.h index e2a4bd01d4..7ee4ddb5c8 100644 --- a/test/unit-test/FreeRTOS_Sockets_DiffConfig/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_Sockets_DiffConfig/FreeRTOSIPConfig.h @@ -103,7 +103,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_Sockets_DiffConfig1/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_Sockets_DiffConfig1/FreeRTOSIPConfig.h index 9612b56339..0d0f470162 100644 --- a/test/unit-test/FreeRTOS_Sockets_DiffConfig1/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_Sockets_DiffConfig1/FreeRTOSIPConfig.h @@ -105,7 +105,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_TCP_IP_DiffConfig/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_TCP_IP_DiffConfig/FreeRTOSIPConfig.h index 8844db6d2c..795be08a9b 100644 --- a/test/unit-test/FreeRTOS_TCP_IP_DiffConfig/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_TCP_IP_DiffConfig/FreeRTOSIPConfig.h @@ -103,7 +103,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_TCP_Reception/FreeRTOS_TCP_Reception_utest.c b/test/unit-test/FreeRTOS_TCP_Reception/FreeRTOS_TCP_Reception_utest.c index a16b3237ea..734210ddc6 100644 --- a/test/unit-test/FreeRTOS_TCP_Reception/FreeRTOS_TCP_Reception_utest.c +++ b/test/unit-test/FreeRTOS_TCP_Reception/FreeRTOS_TCP_Reception_utest.c @@ -557,6 +557,36 @@ void test_prvSingleStepTCPHeaderOptions_Invalid_Length_WS( void ) TEST_ASSERT_EQUAL( -1, result ); } +/* Test for prvSingleStepTCPHeaderOptions function with valid WSopt value. */ +void test_prvSingleStepTCPHeaderOptions_Valid_WS( void ) +{ + int32_t result; + + /* Setup TCP option for tests */ + pxNetworkBuffer = &xNetworkBuffer; + pxNetworkBuffer->pucEthernetBuffer = ucEthernetBuffer; + size_t uxTCPHeaderOffset = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER; + + ProtocolHeaders_t * pxProtocolHeader = ( ( ProtocolHeaders_t * ) + &( pxNetworkBuffer->pucEthernetBuffer[ ( size_t ) ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER ] ) ); + TCPHeader_t * pxTCPHeader = &( pxProtocolHeader->xTCPHeader ); + + pxTCPHeader->ucTCPOffset = 0x80; + pxNetworkBuffer->xDataLength = 0x50; + /* Input TCP option is tcpTCP_OPT_WSOPT, length 3 bytes, and the value is 6. */ + uint8_t ucTCPOptions[] = { 0x03, 0x03, 0x06 }; + memcpy( ( void * ) pxTCPHeader->ucOptdata, ( void * ) &ucTCPOptions, sizeof( ucTCPOptions ) ); + + result = prvSingleStepTCPHeaderOptions( + pxTCPHeader->ucOptdata, + 3, + pxSocket, + pdTRUE ); + + TEST_ASSERT_EQUAL( 3, result ); + TEST_ASSERT_EQUAL( 6, pxSocket->u.xTCP.ucPeerWinScaleFactor ); +} + static uint32_t ulCalled = 0; static void xLocalFunctionPointer( Socket_t xSocket, size_t xLength ) diff --git a/test/unit-test/FreeRTOS_TCP_WIN/FreeRTOS_TCP_WIN_utest.c b/test/unit-test/FreeRTOS_TCP_WIN/FreeRTOS_TCP_WIN_utest.c index ce85357309..e990fe2597 100644 --- a/test/unit-test/FreeRTOS_TCP_WIN/FreeRTOS_TCP_WIN_utest.c +++ b/test/unit-test/FreeRTOS_TCP_WIN/FreeRTOS_TCP_WIN_utest.c @@ -49,6 +49,10 @@ #include "mock_FreeRTOS_IP.h" #include "mock_task.h" +#define winSRTT_INCREMENT_NEW 2 /**< New increment for the smoothed RTT. */ +#define winSRTT_INCREMENT_CURRENT 6 /**< Current increment for the smoothed RTT. */ +#define winSRTT_DECREMENT_NEW 1 /**< New decrement for the smoothed RTT. */ +#define winSRTT_DECREMENT_CURRENT 7 /**< Current decrement for the smoothed RTT. */ static void initializeList( List_t * const pxList ); @@ -2477,6 +2481,9 @@ void test_ulTCPWindowTxSack( void ) /* --->ulTimerGetAge */ xTaskGetTickCount_ExpectAndReturn( 23 ); /* -->prvTCPWindowTxCheckAck_CalcSRTT */ + FreeRTOS_multiply_int32_ExpectAndReturn( 23, winSRTT_DECREMENT_NEW, 23 * winSRTT_DECREMENT_NEW ); + FreeRTOS_multiply_int32_ExpectAndReturn( xWindow.lSRTT, winSRTT_DECREMENT_CURRENT, xWindow.lSRTT * winSRTT_DECREMENT_CURRENT ); + FreeRTOS_add_int32_ExpectAndReturn( xWindow.lSRTT * winSRTT_DECREMENT_CURRENT, 23 * winSRTT_DECREMENT_NEW, xWindow.lSRTT * winSRTT_DECREMENT_CURRENT + 23 * winSRTT_DECREMENT_NEW ); /* ->prvTCPWindowTxCheckAck */ uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); /* ulTCPWindowTxSack */ @@ -2521,6 +2528,10 @@ void test_ulTCPWindowTxSack_prvTCPWindowFastRetransmit_1( void ) /* -->prvTCPWindowTxCheckAck_CalcSRTT */ /* --->ulTimerGetAge */ xTaskGetTickCount_ExpectAndReturn( 69 ); + FreeRTOS_multiply_int32_ExpectAndReturn( 69, winSRTT_INCREMENT_NEW, 69 * winSRTT_INCREMENT_NEW ); + FreeRTOS_multiply_int32_ExpectAndReturn( xWindow.lSRTT, winSRTT_INCREMENT_CURRENT, xWindow.lSRTT * winSRTT_INCREMENT_CURRENT ); + FreeRTOS_add_int32_ExpectAndReturn( xWindow.lSRTT * winSRTT_INCREMENT_CURRENT, 69 * winSRTT_INCREMENT_NEW, xWindow.lSRTT * winSRTT_INCREMENT_CURRENT + 69 * winSRTT_INCREMENT_NEW ); + /* <--prvTCPWindowTxCheckAck_CalcSRTT */ /* <-prvTCPWindowTxCheckAck */ /* ulTCPWindowTxSack */ @@ -2701,3 +2712,54 @@ void test_ulTCPWindowTxSack_prvTCPWindowFastRetransmit_4_LoggingLTZero( void ) xTCPWindowLoggingLevel = xBackup; } + + +void test_ulTCPWindowTxSack_prvTCPWindowFastRetransmit_5_ulTimerGetAgeReturnNegative( void ) +{ + uint32_t ulAckCount; + TCPWindow_t xWindow; + uint32_t ulFirst = 33; + uint32_t ulLast = 63; + TCPSegment_t mockSegment; + ListItem_t mockListItem; + + initializeListItem( &mockListItem ); + + xWindow.tx.ulCurrentSequenceNumber = 32; + xWindow.lSRTT = ipconfigTCP_SRTT_MINIMUM_VALUE_MS + 30; + mockSegment.u.bits.bAcked = pdFALSE_UNSIGNED; + mockSegment.lDataLength = 30; + + mockSegment.u.bits.ucTransmitCount = 1U; + mockSegment.ulSequenceNumber = 33; + mockListItem.pxContainer = &xWindow.xPriorityQueue; + mockSegment.xQueueItem = mockListItem; + mockSegment.xQueueItem.pxContainer = NULL; + mockSegment.u.bits.ucDupAckCount = 1U; + + /* ->prvTCPWindowTxCheckAck */ + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) &mockListItem ); + listGET_LIST_ITEM_OWNER_ExpectAnyArgsAndReturn( &mockSegment ); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) &xWindow.xTxSegments.xListEnd ); + /* -->prvTCPWindowTxCheckAck_CalcSRTT */ + /* --->ulTimerGetAge */ + xTaskGetTickCount_ExpectAndReturn( 0xFFFFFFFF ); /* prvTCPWindowTxCheckAck_CalcSRTT replaces negative value with ipINT32_MAX_VALUE. */ + FreeRTOS_multiply_int32_ExpectAndReturn( ipINT32_MAX_VALUE, winSRTT_INCREMENT_NEW, ipINT32_MAX_VALUE ); + FreeRTOS_multiply_int32_ExpectAndReturn( xWindow.lSRTT, winSRTT_INCREMENT_CURRENT, xWindow.lSRTT * winSRTT_INCREMENT_CURRENT ); + FreeRTOS_add_int32_ExpectAndReturn( xWindow.lSRTT * winSRTT_INCREMENT_CURRENT, ipINT32_MAX_VALUE, ipINT32_MAX_VALUE ); + + /* <--prvTCPWindowTxCheckAck_CalcSRTT */ + /* <-prvTCPWindowTxCheckAck */ + /* ulTCPWindowTxSack */ + /* ->prvTCPWindowFastRetransmit */ + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) &mockListItem ); + listGET_LIST_ITEM_OWNER_ExpectAnyArgsAndReturn( &mockSegment ); + /* exit the loop */ + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) &xWindow.xWaitQueue.xListEnd ); + + ulAckCount = ulTCPWindowTxSack( &xWindow, + ulFirst, + ulLast ); + TEST_ASSERT_EQUAL( 0, ulAckCount ); + TEST_ASSERT_EQUAL( 268435455, xWindow.lSRTT ); /* Expected result is: ( 0x7FFFFFFF / 8 ). */ +} diff --git a/test/unit-test/FreeRTOS_Tiny_TCP/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_Tiny_TCP/FreeRTOSIPConfig.h index a4e4b21864..b4cdb02448 100644 --- a/test/unit-test/FreeRTOS_Tiny_TCP/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_Tiny_TCP/FreeRTOSIPConfig.h @@ -103,7 +103,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_UDP_IPv4/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_UDP_IPv4/FreeRTOSIPConfig.h index c11bb29789..b9c0a2db31 100644 --- a/test/unit-test/FreeRTOS_UDP_IPv4/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_UDP_IPv4/FreeRTOSIPConfig.h @@ -108,7 +108,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1 diff --git a/test/unit-test/FreeRTOS_UDP_IPv6/FreeRTOSIPConfig.h b/test/unit-test/FreeRTOS_UDP_IPv6/FreeRTOSIPConfig.h index 4d29f511c0..ecec28ac5c 100644 --- a/test/unit-test/FreeRTOS_UDP_IPv6/FreeRTOSIPConfig.h +++ b/test/unit-test/FreeRTOS_UDP_IPv6/FreeRTOSIPConfig.h @@ -107,7 +107,7 @@ /* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the * network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK * is not set to 1 then the network event hook will never be called. See: - * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml. + * https://freertos.org/Documentation/03-Libraries/02-FreeRTOS-plus/02-FreeRTOS-plus-TCP/09-API-reference/57-vApplicationIPNetworkEventHook. */ #define ipconfigUSE_NETWORK_EVENT_HOOK 1