Skip to content

Commit

Permalink
Check minimum size of ICMPv6 packets (FreeRTOS#994)
Browse files Browse the repository at this point in the history
* Not all ICMPv6 packets have the same minimum length

* More precise length checking

* Repaired unit tests / coverage

* Running uncrustify

---------

Co-authored-by: Tony Josi <[email protected]>
Co-authored-by: ActoryOu <[email protected]>
Co-authored-by: kar-rahul-aws <[email protected]>
Co-authored-by: Monika Singh <[email protected]>
  • Loading branch information
5 people authored Oct 6, 2023
1 parent 16a74c3 commit 160fa29
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 3 deletions.
24 changes: 23 additions & 1 deletion source/FreeRTOS_IPv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,29 @@ const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0U, 0U, 0U, 0U, 0U, 0
}
else if( ucNextHeader == ( uint8_t ) ipPROTOCOL_ICMP_IPv6 )
{
uxMinimumLength = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxExtHeaderLength + ipSIZE_OF_ICMPv6_HEADER;
uint8_t ucTypeOfMessage;

uxMinimumLength = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + uxExtHeaderLength;

ucTypeOfMessage = pucEthernetBuffer[ uxMinimumLength ];

if( ( ucTypeOfMessage == ipICMP_PING_REQUEST_IPv6 ) ||
( ucTypeOfMessage == ipICMP_PING_REPLY_IPv6 ) )
{
uxMinimumLength += sizeof( ICMPEcho_IPv6_t );
}
else if( ucTypeOfMessage == ipICMP_ROUTER_SOLICITATION_IPv6 )
{
uxMinimumLength += sizeof( ICMPRouterSolicitation_IPv6_t );
}
else if( ucTypeOfMessage == ipICMP_ROUTER_ADVERTISEMENT_IPv6 )
{
uxMinimumLength += sizeof( ICMPRouterAdvertisement_IPv6_t );
}
else
{
uxMinimumLength += ipSIZE_OF_ICMPv6_HEADER;
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_UDP_min_req
}

/**
* @brief test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement
* @brief test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_1
* The buffer size is less than ICMP packet minimal requirement. Check if prvAllowIPPacketIPv6 determines to release it.
*/
void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement()
void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_1()
{
eFrameProcessingResult_t eResult;
NetworkBufferDescriptor_t * pxNetworkBuffer = prvInitializeNetworkDescriptor();
Expand All @@ -241,12 +241,95 @@ void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_re
/* Set next header to ICMPv6 */
pxIPPacket->xIPHeader.ucNextHeader = ipPROTOCOL_ICMP_IPv6;
pxNetworkBuffer->xDataLength = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + 1;
pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ] = ipICMP_ROUTER_SOLICITATION_IPv6;
pxIPPacket->xIPHeader.usPayloadLength = FreeRTOS_htons( 1 );

eResult = prvAllowIPPacketIPv6( &pxIPPacket->xIPHeader, pxNetworkBuffer, 0U );
TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
}

/**
* @brief test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_2
* The buffer size is less than ICMP packet minimal requirement. Check if prvAllowIPPacketIPv6 determines to release it.
*/
void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_2()
{
eFrameProcessingResult_t eResult;
NetworkBufferDescriptor_t * pxNetworkBuffer = prvInitializeNetworkDescriptor();
IPPacket_IPv6_t * pxIPPacket = ( IPPacket_IPv6_t * ) pxNetworkBuffer->pucEthernetBuffer;

/* Set next header to ICMPv6 */
pxIPPacket->xIPHeader.ucNextHeader = ipPROTOCOL_ICMP_IPv6;
pxNetworkBuffer->xDataLength = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + 1;
pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ] = ipICMP_ROUTER_ADVERTISEMENT_IPv6;
pxIPPacket->xIPHeader.usPayloadLength = FreeRTOS_htons( 1 );

eResult = prvAllowIPPacketIPv6( &pxIPPacket->xIPHeader, pxNetworkBuffer, 0U );
TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
}

/**
* @brief test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_3
* The buffer size is less than ICMP packet minimal requirement. Check if prvAllowIPPacketIPv6 determines to release it.
*/
void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_3()
{
eFrameProcessingResult_t eResult;
NetworkBufferDescriptor_t * pxNetworkBuffer = prvInitializeNetworkDescriptor();
IPPacket_IPv6_t * pxIPPacket = ( IPPacket_IPv6_t * ) pxNetworkBuffer->pucEthernetBuffer;

/* Set next header to ICMPv6 */
pxIPPacket->xIPHeader.ucNextHeader = ipPROTOCOL_ICMP_IPv6;
pxNetworkBuffer->xDataLength = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + 1;
pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ] = ipICMP_PING_REQUEST_IPv6;
pxIPPacket->xIPHeader.usPayloadLength = FreeRTOS_htons( 1 );

eResult = prvAllowIPPacketIPv6( &pxIPPacket->xIPHeader, pxNetworkBuffer, 0U );
TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
}

/**
* @brief test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_4
* The buffer size is less than ICMP packet minimal requirement. Check if prvAllowIPPacketIPv6 determines to release it.
*/
void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_4()
{
eFrameProcessingResult_t eResult;
NetworkBufferDescriptor_t * pxNetworkBuffer = prvInitializeNetworkDescriptor();
IPPacket_IPv6_t * pxIPPacket = ( IPPacket_IPv6_t * ) pxNetworkBuffer->pucEthernetBuffer;

/* Set next header to ICMPv6 */
pxIPPacket->xIPHeader.ucNextHeader = ipPROTOCOL_ICMP_IPv6;
pxNetworkBuffer->xDataLength = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + 1;
pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ] = ipICMP_PING_REPLY_IPv6;
pxIPPacket->xIPHeader.usPayloadLength = FreeRTOS_htons( 1 );

eResult = prvAllowIPPacketIPv6( &pxIPPacket->xIPHeader, pxNetworkBuffer, 0U );
TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
}

/**
* @brief test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_5
* This is the default case for all ICMPv6 packet length testing.
* The buffer size is less than ICMP packet minimal requirement. Check if prvAllowIPPacketIPv6 determines to release it.
*/
void test_prvAllowIPPacketIPv6_xCheckIPv6SizeFields_length_less_than_ICMP_min_requirement_5()
{
eFrameProcessingResult_t eResult;
NetworkBufferDescriptor_t * pxNetworkBuffer = prvInitializeNetworkDescriptor();
IPPacket_IPv6_t * pxIPPacket = ( IPPacket_IPv6_t * ) pxNetworkBuffer->pucEthernetBuffer;

/* Set next header to ICMPv6 */
pxIPPacket->xIPHeader.ucNextHeader = ipPROTOCOL_ICMP_IPv6;
pxNetworkBuffer->xDataLength = ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER + 1;
pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv6_HEADER ] = ipICMP_NEIGHBOR_SOLICITATION_IPv6;
pxIPPacket->xIPHeader.usPayloadLength = FreeRTOS_htons( 1 );

eResult = prvAllowIPPacketIPv6( &pxIPPacket->xIPHeader, pxNetworkBuffer, 0U );
TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
}


/**
* @brief test_prvAllowIPPacketIPv6_source_unspecified_address
* Prepare a packet with unspecified address in source address.
Expand Down

0 comments on commit 160fa29

Please sign in to comment.