Skip to content

Commit

Permalink
Preparing library to use loopback device (#1020)
Browse files Browse the repository at this point in the history
* Preparing library to use loopback device

* Repaired FreeRTOS_AddEndPoint() as well

* Minor changes for Doxygen

* Uncrustify: triggered by comment.

* Added IPv6.h and removed call to xIsIPv6Loopback

* Conditional compilation of xIPv6_GetIPType()

* Do not call xBadIPv4Loopback() when IPv4 is not enabled

* Repaired unit tests

* In FreeRTOS_AddEndPoint(), set next to NULL

* One more change in FreeRTOS_AddNetworkInterface()

* FreeRTOS_FillEndPoint: save pxNext before clearing entire endpoint struct

* Uncrustify: triggered by comment.

* Changes after review by Shub

* Changes after review by Shub, part 2

* Uncrustify: triggered by comment.

* Replace pxUDPPacket with pxIPacket in function prvAllowIPPacketIPv4()

* utest: replace xIPv6UnspecifiedAddress with FreeRTOS_in6addr_any

* Checked unit-tests and coverage

* ut: Repaired GetIPType loopback test

* Update test/unit-test/FreeRTOS_IPv6_ConfigDriverCheckChecksum/FreeRTOS_IPv6_ConfigDriverCheckChecksum_stubs.c

Co-authored-by: ActoryOu <[email protected]>

* Update test/unit-test/FreeRTOS_IPv6/ut.cmake

Co-authored-by: ActoryOu <[email protected]>

* Remove test for 'ipIPv4_FRAME_TYPE'

* Repairing tu again

---------

Co-authored-by: GitHub Action <[email protected]>
Co-authored-by: Monika Singh <[email protected]>
Co-authored-by: Tony Josi <[email protected]>
Co-authored-by: ActoryOu <[email protected]>
  • Loading branch information
5 people authored Oct 6, 2023
1 parent 3cc5d1c commit 16a74c3
Show file tree
Hide file tree
Showing 19 changed files with 441 additions and 136 deletions.
7 changes: 6 additions & 1 deletion source/FreeRTOS_ARP.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,12 @@ BaseType_t xCheckRequiresARPResolution( const NetworkBufferDescriptor_t * pxNetw
( ucNextHeader == ipPROTOCOL_UDP ) )
{
IPv6_Type_t eType = xIPv6_GetIPType( ( const IPv6_Address_t * ) pxIPAddress );
FreeRTOS_printf( ( "xCheckRequiresARPResolution: %pip type %s\n", ( void * ) pxIPAddress->ucBytes, ( eType == eIPv6_Global ) ? "Global" : ( eType == eIPv6_LinkLocal ) ? "LinkLocal" : "other" ) );
FreeRTOS_debug_printf( ( "xCheckRequiresARPResolution: %pip type %s\n",
( void * ) pxIPAddress->ucBytes,
( eType == eIPv6_Global ) ? "Global" :
( eType == eIPv6_LinkLocal ) ? "LinkLocal" :
( eType == eIPv6_Loopback ) ? "Loopback" :
"other" ) );

if( eType == eIPv6_LinkLocal )
{
Expand Down
26 changes: 11 additions & 15 deletions source/FreeRTOS_IP.c
Original file line number Diff line number Diff line change
Expand Up @@ -1702,21 +1702,17 @@ static eFrameProcessingResult_t prvProcessUDPPacket( NetworkBufferDescriptor_t *
/* Note the header values required prior to the checksum
* generation as the checksum pseudo header may clobber some of
* these values. */
if( ( pxUDPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) &&
( usLength > ( FreeRTOS_ntohs( pxUDPPacket->xIPHeader.usLength ) - uxIPHeaderSizePacket( pxNetworkBuffer ) ) ) )
{
eReturn = eReleaseBuffer;
}
else if( ( pxUDPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) &&
( ipFIRST_LOOPBACK_IPv4 <= ( FreeRTOS_ntohl( pxUDPPacket->xIPHeader.ulDestinationIPAddress ) ) ) &&
( ( FreeRTOS_ntohl( pxUDPPacket->xIPHeader.ulDestinationIPAddress ) ) < ipLAST_LOOPBACK_IPv4 ) )
{
/* The local loopback addresses must never appear outside a host. See RFC 1122
* section 3.2.1.3. */
eReturn = eReleaseBuffer;
}
else if( ( pxNetworkBuffer->xDataLength >= uxMinSize ) &&
( uxLength >= sizeof( UDPHeader_t ) ) )
#if ( ipconfigUSE_IPv4 != 0 )
if( ( pxUDPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) &&
( usLength > ( FreeRTOS_ntohs( pxUDPPacket->xIPHeader.usLength ) - uxIPHeaderSizePacket( pxNetworkBuffer ) ) ) )
{
eReturn = eReleaseBuffer;
}
else
#endif /* ( ipconfigUSE_IPv4 != 0 ) */

if( ( pxNetworkBuffer->xDataLength >= uxMinSize ) &&
( uxLength >= sizeof( UDPHeader_t ) ) )
{
size_t uxPayloadSize_1, uxPayloadSize_2;

Expand Down
58 changes: 58 additions & 0 deletions source/FreeRTOS_IPv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,58 @@ BaseType_t xIsIPv4Multicast( uint32_t ulIPAddress )
}
/*-----------------------------------------------------------*/

/**
* @brief Check if the packet is an illegal loopback packet.
*
* @param[in] pxIPHeader The IP-header being checked.
*
* @return Returns pdTRUE if the packet should be stopped, because either the source
* or the target address is a loopback address.
*/
BaseType_t xBadIPv4Loopback( const IPHeader_t * const pxIPHeader )
{
BaseType_t xReturn = pdFALSE;
const NetworkEndPoint_t * pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( pxIPHeader->ulSourceIPAddress, 3 );

/* Allow loopback packets from this node itself only. */
if( pxEndPoint != NULL )
{
BaseType_t x1 = ( xIsIPv4Loopback( pxIPHeader->ulDestinationIPAddress ) != 0 ) ? pdTRUE : pdFALSE;
BaseType_t x2 = ( xIsIPv4Loopback( pxIPHeader->ulSourceIPAddress ) != 0 ) ? pdTRUE : pdFALSE;

if( x1 != x2 )
{
/* Either the source or the destination address is an IPv4 loopback address. */
xReturn = pdTRUE;
}
}

return xReturn;
}
/*-----------------------------------------------------------*/

/**
* @brief Is the IP address an IPv4 loopback address.
*
* @param[in] ulAddress The IP address being checked.
*
* @return pdTRUE if the IP address is a loopback address or else, pdFALSE.
*/
BaseType_t xIsIPv4Loopback( uint32_t ulAddress )
{
BaseType_t xReturn = pdFALSE;
uint32_t ulIP = FreeRTOS_ntohl( ulAddress );

if( ( ulIP >= ipFIRST_LOOPBACK_IPv4 ) &&
( ulIP < ipLAST_LOOPBACK_IPv4 ) )
{
xReturn = pdTRUE;
}

return xReturn;
}
/*-----------------------------------------------------------*/

/**
* @brief Check whether this IPv4 packet is to be allowed or to be dropped.
*
Expand Down Expand Up @@ -260,6 +312,12 @@ enum eFrameProcessingResult prvAllowIPPacketIPv4( const struct xIP_PACKET * cons
/* Can not handle, unknown or invalid header version. */
eReturn = eReleaseBuffer;
}
else if( xBadIPv4Loopback( &( pxIPPacket->xIPHeader ) ) == pdTRUE )
{
/* The local loopback addresses must never appear outside a host. See RFC 1122
* section 3.2.1.3. */
eReturn = eReleaseBuffer;
}
else if(
( FreeRTOS_FindEndPointOnIP_IPv4( ulDestinationIPAddress, 4 ) == NULL ) &&
( pxNetworkBuffer->pxEndPoint == NULL ) &&
Expand Down
68 changes: 40 additions & 28 deletions source/FreeRTOS_IPv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const struct xIPv6_Address FreeRTOS_in6addr_any = { 0 };
/**
* This variable is initialized by the system to contain the loopback IPv6 address.
*/
const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } };
const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U } };

#if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 1 )
/* Check IPv6 packet length. */
Expand Down Expand Up @@ -237,19 +237,6 @@ const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0, 0, 0, 0, 0, 0, 0,
#endif /* ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 1 ) */
/*-----------------------------------------------------------*/

/**
* This variable is initialized by the system to contain the unspecified IPv6 address.
*/
static const struct xIPv6_Address xIPv6UnspecifiedAddress = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };

#if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )

/*
* Check if the packet is a loopback packet.
*/
static BaseType_t xIsIPv6Loopback( const IPHeader_IPv6_t * const pxIPv6Header );
#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 */

/**
* @brief Get the group ID and stored into IPv6_Address_t.
*
Expand All @@ -270,34 +257,60 @@ static void xGetIPv6MulticastGroupID( const IPv6_Address_t * pxIPv6Address,

/*-----------------------------------------------------------*/

/**
* @brief Check if the IP-address is an IPv6 loopback address.
*
* @param[in] pxAddress The IP-address being checked.
*
* @return pdTRUE if the IP-address is a loopback address or else, pdFALSE.
*/
BaseType_t xIsIPv6Loopback( const IPv6_Address_t * pxAddress )
{
BaseType_t xReturn = pdFALSE;

if( memcmp( pxAddress->ucBytes, FreeRTOS_in6addr_loopback.ucBytes, ipSIZE_OF_IPv6_ADDRESS ) == 0 )
{
xReturn = pdTRUE;
}

return xReturn;
}

#if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )

/**
* @brief Check if the packet is a loopback packet.
* @brief Check if the packet is an illegal loopback packet.
*
* @param[in] pxIPv6Header The IP packet in pxNetworkBuffer.
* @param[in] pxIPv6Header The IP-header of the packet.
*
* @return Returns pdTRUE if it's a legal loopback packet, pdFALSE if not .
* @return Returns pdTRUE if the packet should be stopped, because either the source
* or the target address is a loopback address.
*/
/* MISRA Ref 8.9.1 [File scoped variables] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-89 */
/* coverity[misra_c_2012_rule_8_9_violation] */
/* coverity[single_use] */
static BaseType_t xIsIPv6Loopback( const IPHeader_IPv6_t * const pxIPv6Header )
BaseType_t xBadIPv6Loopback( const IPHeader_IPv6_t * const pxIPv6Header )
{
BaseType_t xReturn = pdFALSE;
const NetworkEndPoint_t * pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv6( &( pxIPv6Header->xSourceAddress ) );

/* Allow loopback packets from this node itself only. */
if( ( pxEndPoint != NULL ) &&
( memcmp( pxIPv6Header->xDestinationAddress.ucBytes, FreeRTOS_in6addr_loopback.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) &&
( memcmp( pxIPv6Header->xSourceAddress.ucBytes, pxEndPoint->ipv6_settings.xIPAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
if( pxEndPoint != NULL )
{
xReturn = pdTRUE;
BaseType_t x1 = ( xIsIPv6Loopback( &( pxIPv6Header->xDestinationAddress ) ) != 0 ) ? pdTRUE : pdFALSE;
BaseType_t x2 = ( xIsIPv6Loopback( &( pxIPv6Header->xSourceAddress ) ) != 0 ) ? pdTRUE : pdFALSE;

if( x1 != x2 )
{
/* Either source or the destination address is a loopback address. */
xReturn = pdTRUE;
}
}

return xReturn;
}

#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 */


Expand Down Expand Up @@ -332,7 +345,7 @@ BaseType_t xIsIPv6AllowedMulticast( const IPv6_Address_t * pxIPAddress )
* - ..
* - 0xFF0F:: */
else if( ( IPv6MC_GET_FLAGS_VALUE( pxIPAddress ) == 0U ) &&
( memcmp( xGroupIDAddress.ucBytes, xIPv6UnspecifiedAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
( memcmp( xGroupIDAddress.ucBytes, FreeRTOS_in6addr_any.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
{
xReturn = pdFALSE;
}
Expand Down Expand Up @@ -462,8 +475,8 @@ eFrameProcessingResult_t prvAllowIPPacketIPv6( const IPHeader_IPv6_t * const pxI

/* Drop if packet has unspecified IPv6 address (defined in RFC4291 - sec 2.5.2)
* either in source or destination address. */
if( ( memcmp( pxDestinationIPAddress->ucBytes, xIPv6UnspecifiedAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) ||
( memcmp( pxSourceIPAddress->ucBytes, xIPv6UnspecifiedAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
if( ( memcmp( pxDestinationIPAddress->ucBytes, FreeRTOS_in6addr_any.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) ||
( memcmp( pxSourceIPAddress->ucBytes, FreeRTOS_in6addr_any.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
{
xHasUnspecifiedAddress = pdTRUE;
}
Expand All @@ -476,10 +489,9 @@ eFrameProcessingResult_t prvAllowIPPacketIPv6( const IPHeader_IPv6_t * const pxI
eReturn = eProcessBuffer;
}
/* Is it the legal multicast address? */
else if( ( xHasUnspecifiedAddress == pdFALSE ) &&
else if( ( ( xHasUnspecifiedAddress == pdFALSE ) &&
( xBadIPv6Loopback( pxIPv6Header ) == pdFALSE ) ) &&
( ( xIsIPv6AllowedMulticast( pxDestinationIPAddress ) != pdFALSE ) ||
/* Is it loopback address sent from this node? */
( xIsIPv6Loopback( pxIPv6Header ) != pdFALSE ) ||
/* Or (during DHCP negotiation) we have no IP-address yet? */
( FreeRTOS_IsNetworkUp() == 0 ) ) )
{
Expand Down
3 changes: 2 additions & 1 deletion source/FreeRTOS_ND.c
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,8 @@

if( xResult == pdPASS )
{
configASSERT( ( uxPrefixLength > 0U ) && ( uxPrefixLength < ( 8U * ipSIZE_OF_IPv6_ADDRESS ) ) );
/* A loopback IP-address has a prefix of 128. */
configASSERT( ( uxPrefixLength > 0U ) && ( uxPrefixLength <= ( 8U * ipSIZE_OF_IPv6_ADDRESS ) ) );

if( uxPrefixLength >= 8U )
{
Expand Down
Loading

0 comments on commit 16a74c3

Please sign in to comment.