Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 64 additions & 31 deletions source/FreeRTOS_IPv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,35 +378,6 @@ enum eFrameProcessingResult prvAllowIPPacketIPv4( const struct xIP_PACKET * cons
eReturn = eReleaseBuffer;
}
}
else if(
/* Not destined for the assigned endpoint IPv4 address? */
( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulIPAddress ) &&
/* Also not an IPv4 broadcast address ? */
( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulBroadcastAddress ) &&
( ulDestinationIPAddress != FREERTOS_INADDR_BROADCAST ) &&
/* And not an IPv4 multicast address ? */
( xIsIPv4Multicast( ulDestinationIPAddress ) == pdFALSE ) )
{
/* Packet is not for this node, release it */
eReturn = eReleaseBuffer;
}
/* Is the source address correct? */
else if( ( ulSourceIPAddress == pxEndPoint->ipv4_settings.ulBroadcastAddress ) ||
( ulSourceIPAddress == FREERTOS_INADDR_BROADCAST ) )
{
/* The source address cannot be broadcast address. Replying to this
* packet may cause network storms. Drop the packet. */
eReturn = eReleaseBuffer;
}
else if( ( memcmp( xBroadcastMACAddress.ucBytes,
pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes,
sizeof( MACAddress_t ) ) == 0 ) &&
( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulBroadcastAddress ) && ( ulDestinationIPAddress != FREERTOS_INADDR_BROADCAST ) )
{
/* Ethernet address is a broadcast address, but the IP address is not a
* broadcast address. */
eReturn = eReleaseBuffer;
}
else if( memcmp( xBroadcastMACAddress.ucBytes,
pxIPPacket->xEthernetHeader.xSourceAddress.ucBytes,
sizeof( MACAddress_t ) ) == 0 )
Expand All @@ -419,10 +390,72 @@ enum eFrameProcessingResult prvAllowIPPacketIPv4( const struct xIP_PACKET * cons
/* Source is a multicast IP address. Drop the packet in conformity with RFC 1112 section 7.2. */
eReturn = eReleaseBuffer;
}

/* Use ipv4_settings for filtering only after the endpoint is up,
* so that DHCP packets that are exchanged for DHCP (example, DHCP unicast offers)
* are not dropped/filtered. */
else if( FreeRTOS_IsEndPointUp( pxEndPoint ) != pdFALSE )
{
if(
/* Not destined for the assigned endpoint IPv4 address? */
( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulIPAddress ) &&
/* Also not an IPv4 broadcast address ? */
( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulBroadcastAddress ) &&
( ulDestinationIPAddress != FREERTOS_INADDR_BROADCAST ) &&
/* And not an IPv4 multicast address ? */
( xIsIPv4Multicast( ulDestinationIPAddress ) == pdFALSE ) )
{
/* Packet is not for this node, release it */
eReturn = eReleaseBuffer;
}
/* Is the source address correct? */
else if( ( ulSourceIPAddress == pxEndPoint->ipv4_settings.ulBroadcastAddress ) ||
( ulSourceIPAddress == FREERTOS_INADDR_BROADCAST ) )
{
/* The source address cannot be broadcast address. Replying to this
* packet may cause network storms. Drop the packet. */
eReturn = eReleaseBuffer;
}
else if( ( memcmp( xBroadcastMACAddress.ucBytes,
pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes,
sizeof( MACAddress_t ) ) == 0 ) &&
( ulDestinationIPAddress != pxEndPoint->ipv4_settings.ulBroadcastAddress ) && ( ulDestinationIPAddress != FREERTOS_INADDR_BROADCAST ) )
{
/* Ethernet address is a broadcast address, but the IP address is not a
* broadcast address. */
eReturn = eReleaseBuffer;
}
else
{
/* Packet is not fragmented, destination is this device, source IP and MAC
* addresses are correct. */
}
}
else
{
/* Packet is not fragmented, destination is this device, source IP and MAC
* addresses are correct. */
/* Endpoint is down */

/* RFC 2131: https://datatracker.ietf.org/doc/html/rfc2131#autoid-8
* The TCP/IP software SHOULD accept and
* forward to the IP layer any IP packets delivered to the client's
* hardware address before the IP address is configured; DHCP servers
* and BOOTP relay agents may not be able to deliver DHCP messages to
* clients that cannot accept hardware unicast datagrams before the
* TCP/IP software is configured. */
if( ( memcmp( pxEndPoint->xMACAddress.ucBytes,
pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes,
sizeof( MACAddress_t ) ) != 0 ) )
{
/* The endpoint is not up, and the destination MAC address of the
* packet is not matching the endpoint's MAC address. Drop the
* packet. */
eReturn = eReleaseBuffer;
}
else
{
/* Endpoint is down, but the hardware address matches. Accept the
* packet as per RFC 2131 */
}
}
}
#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
Expand Down
97 changes: 96 additions & 1 deletion test/unit-test/FreeRTOS_IPv4/FreeRTOS_IPv4_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "mock_event_groups.h"

#include "mock_FreeRTOS_IP.h"
#include "mock_FreeRTOS_IP_Common.h"
#include "mock_FreeRTOS_IP_Private.h"
#include "mock_FreeRTOS_Routing.h"

Expand Down Expand Up @@ -396,6 +397,8 @@ void test_prvAllowIPPacketIPv4_NotMatchingIP( void )
pxIPHeader->ucVersionHeaderLength = 0x45;
pxIPHeader->ulDestinationIPAddress = pxEndpoint->ipv4_settings.ulIPAddress + 1;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
Expand Down Expand Up @@ -432,6 +435,8 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPMatch( void )

pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
Expand Down Expand Up @@ -469,6 +474,7 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPBrdCast( void )

pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

Expand Down Expand Up @@ -507,6 +513,7 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_DestIPLLMNR( void )

pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

Expand Down Expand Up @@ -541,6 +548,7 @@ void test_prvAllowIPPacketIPv4_SourceIPBrdCast_NoLocalIP( void )
pxIPHeader->ulDestinationIPAddress = 0;

pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF;
FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

Expand Down Expand Up @@ -577,6 +585,87 @@ void test_prvAllowIPPacketIPv4_DestMACBrdCast_DestIPUnicast( void )

memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
}

/**
* @brief test_prvAllowIPPacketIPv4_EndpointDown_HappyPath
* To validate if prvAllowIPPacketIPv4() returns eProcessBuffer when
* endpoint is down but the destination MAC address matches the MAC address of
* the endpoint.
*/
void test_prvAllowIPPacketIPv4_EndpointDown_HappyPath( void )
{
eFrameProcessingResult_t eResult;
IPPacket_t * pxIPPacket;
NetworkBufferDescriptor_t * pxNetworkBuffer, xNetworkBuffer;
UBaseType_t uxHeaderLength = 0;
uint8_t ucEthBuffer[ ipconfigTCP_MSS ];
IPHeader_t * pxIPHeader;
NetworkEndPoint_t xEndpoint;

memset( ucEthBuffer, 0, ipconfigTCP_MSS );

pxNetworkBuffer = &xNetworkBuffer;
pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer;
pxNetworkBuffer->pxEndPoint = &xEndpoint;
pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
pxIPHeader = &( pxIPPacket->xIPHeader );

pxIPHeader->ucVersionHeaderLength = 0x45;

pxIPHeader->ulDestinationIPAddress = 0x00;

memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xEndpoint.xMACAddress.ucBytes, sizeof( MACAddress_t ) );

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdFALSE );
FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL );

usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC );

usGenerateProtocolChecksum_ExpectAndReturn( ( uint8_t * ) ( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength, pdFALSE, ipCORRECT_CRC );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eProcessBuffer, eResult );
}

/**
* @brief test_prvAllowIPPacketIPv4_EndpointDown_HappyPath
* To validate if prvAllowIPPacketIPv4() returns eReleaseBuffer when
* endpoint is down but the destination MAC address does not match the MAC address of
* the endpoint.
*/
void test_prvAllowIPPacketIPv4_EndpointDown_UnHappyPath( void )
{
eFrameProcessingResult_t eResult;
IPPacket_t * pxIPPacket;
NetworkBufferDescriptor_t * pxNetworkBuffer, xNetworkBuffer;
UBaseType_t uxHeaderLength = 0;
uint8_t ucEthBuffer[ ipconfigTCP_MSS ];
IPHeader_t * pxIPHeader;
NetworkEndPoint_t xEndpoint;

memset( ucEthBuffer, 0, ipconfigTCP_MSS );

pxNetworkBuffer = &xNetworkBuffer;
pxNetworkBuffer->pucEthernetBuffer = ucEthBuffer;
pxNetworkBuffer->pxEndPoint = &xEndpoint;
pxIPPacket = ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
pxIPHeader = &( pxIPPacket->xIPHeader );

pxIPHeader->ucVersionHeaderLength = 0x45;

pxIPHeader->ulDestinationIPAddress = 0x00;

memset( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, 0xAB, sizeof( MACAddress_t ) );
memset( xEndpoint.xMACAddress.ucBytes, 0xCD, sizeof( MACAddress_t ) );

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdFALSE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

Expand Down Expand Up @@ -613,6 +702,7 @@ void test_prvAllowIPPacketIPv4_DestMACBrdCast_DestIPBroadcastAndIncorrectChkSum(
xEndpoint.ipv4_settings.ulBroadcastAddress = 0xABCDFFFF;

memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );
FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL );

Expand Down Expand Up @@ -769,6 +859,7 @@ void test_prvAllowIPPacketIPv4_IncorrectChecksum( void )

pxIPHeader->ulSourceIPAddress = 0xC0C00101;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );
FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL );

usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC - 1 );
Expand Down Expand Up @@ -812,6 +903,7 @@ void test_prvAllowIPPacketIPv4_IncorrectProtocolChecksum( void )

pxIPHeader->ulSourceIPAddress = 0xC0C00101;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );
FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL );

usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC );
Expand Down Expand Up @@ -856,7 +948,7 @@ void test_prvAllowIPPacketIPv4_HappyPath( void )

pxIPHeader->ulSourceIPAddress = 0xC0C00101;


FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );
FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL );

usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC );
Expand Down Expand Up @@ -939,6 +1031,7 @@ void test_prvAllowIPPacketIPv4_DestMacBroadcastIPNotBroadcast( void )
memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );

pxIPHeader->ulSourceIPAddress = 0xC0C00101;
FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

Expand Down Expand Up @@ -1106,6 +1199,8 @@ void test_xBadIPv4Loopback_0_test( void )

memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xMACAddress.ucBytes, sizeof( MACAddress_t ) );

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

FreeRTOS_FindEndPointOnMAC_ExpectAnyArgsAndReturn( NULL );

usGenerateChecksum_ExpectAndReturn( 0U, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength, ipCORRECT_CRC );
Expand Down
1 change: 1 addition & 0 deletions test/unit-test/FreeRTOS_IPv4/ut.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ list(APPEND mock_list
"${MODULE_ROOT_DIR}/test/FreeRTOS-Kernel/include/queue.h"
"${MODULE_ROOT_DIR}/test/FreeRTOS-Kernel/include/event_groups.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Common.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Private.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IPv6.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_Routing.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

/* This must come after list.h is included (in this case, indirectly
* by mock_list.h). */
#include "mock_FreeRTOS_IP_Common.h"
#include "mock_IPv4_DiffConfig_list_macros.h"
#include "mock_queue.h"
#include "mock_event_groups.h"
Expand Down Expand Up @@ -105,7 +106,7 @@ void test_prvAllowIPPacketIPv4_BroadcastSourceIP( void )
memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );

pxIPHeader->ulSourceIPAddress = 0xFFFFFFFF;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );
eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
Expand Down Expand Up @@ -146,7 +147,7 @@ void test_prvAllowIPPacketIPv4_BufferLengthLessThanMinimum( void )

pxIPHeader->ulSourceIPAddress = 0xC0C00101;


FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );
eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
Expand Down Expand Up @@ -191,7 +192,7 @@ void test_prvAllowIPPacketIPv4_UDPCheckSumZero( void )

pxIPHeader->ulSourceIPAddress = 0xC0C00101;


FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );
eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eReleaseBuffer, eResult );
Expand Down Expand Up @@ -242,7 +243,7 @@ void test_prvAllowIPPacketIPv4_UDP_HappyPath( void )
/* Non-zero checksum. */
pxProtPack->xUDPPacket.xUDPHeader.usChecksum = 0xFF12;


FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );
eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

TEST_ASSERT_EQUAL( eProcessBuffer, eResult );
Expand Down Expand Up @@ -286,7 +287,7 @@ void test_prvAllowIPPacketIPv4_TCP_HappyPath( void )
memcpy( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );

pxIPHeader->ulSourceIPAddress = 0xC0C00101;

FreeRTOS_IsEndPointUp_ExpectAndReturn( &xEndpoint, pdTRUE );

eResult = prvAllowIPPacketIPv4( pxIPPacket, pxNetworkBuffer, uxHeaderLength );

Expand Down
1 change: 1 addition & 0 deletions test/unit-test/FreeRTOS_IPv4_DiffConfig/ut.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ list(APPEND mock_list
"${MODULE_ROOT_DIR}/test/FreeRTOS-Kernel/include/queue.h"
"${MODULE_ROOT_DIR}/test/FreeRTOS-Kernel/include/event_groups.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Common.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Timers.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Utils.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_Routing.h"
Expand Down
1 change: 1 addition & 0 deletions test/unit-test/FreeRTOS_IPv4_DiffConfig1/ut.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ list(APPEND mock_list
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Timers.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Utils.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_IP_Common.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_Routing.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_ARP.h"
"${CMAKE_BINARY_DIR}/Annexed_TCP/FreeRTOS_ICMP.h"
Expand Down
Loading