Skip to content

Commit 16a74c3

Browse files
htiboschactions-usermoninom1tony-josi-awsActoryOu
authored
Preparing library to use loopback device (#1020)
* 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]>
1 parent 3cc5d1c commit 16a74c3

File tree

19 files changed

+441
-136
lines changed

19 files changed

+441
-136
lines changed

source/FreeRTOS_ARP.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,12 @@ BaseType_t xCheckRequiresARPResolution( const NetworkBufferDescriptor_t * pxNetw
565565
( ucNextHeader == ipPROTOCOL_UDP ) )
566566
{
567567
IPv6_Type_t eType = xIPv6_GetIPType( ( const IPv6_Address_t * ) pxIPAddress );
568-
FreeRTOS_printf( ( "xCheckRequiresARPResolution: %pip type %s\n", ( void * ) pxIPAddress->ucBytes, ( eType == eIPv6_Global ) ? "Global" : ( eType == eIPv6_LinkLocal ) ? "LinkLocal" : "other" ) );
568+
FreeRTOS_debug_printf( ( "xCheckRequiresARPResolution: %pip type %s\n",
569+
( void * ) pxIPAddress->ucBytes,
570+
( eType == eIPv6_Global ) ? "Global" :
571+
( eType == eIPv6_LinkLocal ) ? "LinkLocal" :
572+
( eType == eIPv6_Loopback ) ? "Loopback" :
573+
"other" ) );
569574

570575
if( eType == eIPv6_LinkLocal )
571576
{

source/FreeRTOS_IP.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,21 +1702,17 @@ static eFrameProcessingResult_t prvProcessUDPPacket( NetworkBufferDescriptor_t *
17021702
/* Note the header values required prior to the checksum
17031703
* generation as the checksum pseudo header may clobber some of
17041704
* these values. */
1705-
if( ( pxUDPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) &&
1706-
( usLength > ( FreeRTOS_ntohs( pxUDPPacket->xIPHeader.usLength ) - uxIPHeaderSizePacket( pxNetworkBuffer ) ) ) )
1707-
{
1708-
eReturn = eReleaseBuffer;
1709-
}
1710-
else if( ( pxUDPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) &&
1711-
( ipFIRST_LOOPBACK_IPv4 <= ( FreeRTOS_ntohl( pxUDPPacket->xIPHeader.ulDestinationIPAddress ) ) ) &&
1712-
( ( FreeRTOS_ntohl( pxUDPPacket->xIPHeader.ulDestinationIPAddress ) ) < ipLAST_LOOPBACK_IPv4 ) )
1713-
{
1714-
/* The local loopback addresses must never appear outside a host. See RFC 1122
1715-
* section 3.2.1.3. */
1716-
eReturn = eReleaseBuffer;
1717-
}
1718-
else if( ( pxNetworkBuffer->xDataLength >= uxMinSize ) &&
1719-
( uxLength >= sizeof( UDPHeader_t ) ) )
1705+
#if ( ipconfigUSE_IPv4 != 0 )
1706+
if( ( pxUDPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE ) &&
1707+
( usLength > ( FreeRTOS_ntohs( pxUDPPacket->xIPHeader.usLength ) - uxIPHeaderSizePacket( pxNetworkBuffer ) ) ) )
1708+
{
1709+
eReturn = eReleaseBuffer;
1710+
}
1711+
else
1712+
#endif /* ( ipconfigUSE_IPv4 != 0 ) */
1713+
1714+
if( ( pxNetworkBuffer->xDataLength >= uxMinSize ) &&
1715+
( uxLength >= sizeof( UDPHeader_t ) ) )
17201716
{
17211717
size_t uxPayloadSize_1, uxPayloadSize_2;
17221718

source/FreeRTOS_IPv4.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,58 @@ BaseType_t xIsIPv4Multicast( uint32_t ulIPAddress )
210210
}
211211
/*-----------------------------------------------------------*/
212212

213+
/**
214+
* @brief Check if the packet is an illegal loopback packet.
215+
*
216+
* @param[in] pxIPHeader The IP-header being checked.
217+
*
218+
* @return Returns pdTRUE if the packet should be stopped, because either the source
219+
* or the target address is a loopback address.
220+
*/
221+
BaseType_t xBadIPv4Loopback( const IPHeader_t * const pxIPHeader )
222+
{
223+
BaseType_t xReturn = pdFALSE;
224+
const NetworkEndPoint_t * pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( pxIPHeader->ulSourceIPAddress, 3 );
225+
226+
/* Allow loopback packets from this node itself only. */
227+
if( pxEndPoint != NULL )
228+
{
229+
BaseType_t x1 = ( xIsIPv4Loopback( pxIPHeader->ulDestinationIPAddress ) != 0 ) ? pdTRUE : pdFALSE;
230+
BaseType_t x2 = ( xIsIPv4Loopback( pxIPHeader->ulSourceIPAddress ) != 0 ) ? pdTRUE : pdFALSE;
231+
232+
if( x1 != x2 )
233+
{
234+
/* Either the source or the destination address is an IPv4 loopback address. */
235+
xReturn = pdTRUE;
236+
}
237+
}
238+
239+
return xReturn;
240+
}
241+
/*-----------------------------------------------------------*/
242+
243+
/**
244+
* @brief Is the IP address an IPv4 loopback address.
245+
*
246+
* @param[in] ulAddress The IP address being checked.
247+
*
248+
* @return pdTRUE if the IP address is a loopback address or else, pdFALSE.
249+
*/
250+
BaseType_t xIsIPv4Loopback( uint32_t ulAddress )
251+
{
252+
BaseType_t xReturn = pdFALSE;
253+
uint32_t ulIP = FreeRTOS_ntohl( ulAddress );
254+
255+
if( ( ulIP >= ipFIRST_LOOPBACK_IPv4 ) &&
256+
( ulIP < ipLAST_LOOPBACK_IPv4 ) )
257+
{
258+
xReturn = pdTRUE;
259+
}
260+
261+
return xReturn;
262+
}
263+
/*-----------------------------------------------------------*/
264+
213265
/**
214266
* @brief Check whether this IPv4 packet is to be allowed or to be dropped.
215267
*
@@ -260,6 +312,12 @@ enum eFrameProcessingResult prvAllowIPPacketIPv4( const struct xIP_PACKET * cons
260312
/* Can not handle, unknown or invalid header version. */
261313
eReturn = eReleaseBuffer;
262314
}
315+
else if( xBadIPv4Loopback( &( pxIPPacket->xIPHeader ) ) == pdTRUE )
316+
{
317+
/* The local loopback addresses must never appear outside a host. See RFC 1122
318+
* section 3.2.1.3. */
319+
eReturn = eReleaseBuffer;
320+
}
263321
else if(
264322
( FreeRTOS_FindEndPointOnIP_IPv4( ulDestinationIPAddress, 4 ) == NULL ) &&
265323
( pxNetworkBuffer->pxEndPoint == NULL ) &&

source/FreeRTOS_IPv6.c

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const struct xIPv6_Address FreeRTOS_in6addr_any = { 0 };
6262
/**
6363
* This variable is initialized by the system to contain the loopback IPv6 address.
6464
*/
65-
const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } };
65+
const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U } };
6666

6767
#if ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 1 )
6868
/* Check IPv6 packet length. */
@@ -237,19 +237,6 @@ const struct xIPv6_Address FreeRTOS_in6addr_loopback = { { 0, 0, 0, 0, 0, 0, 0,
237237
#endif /* ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 1 ) */
238238
/*-----------------------------------------------------------*/
239239

240-
/**
241-
* This variable is initialized by the system to contain the unspecified IPv6 address.
242-
*/
243-
static const struct xIPv6_Address xIPv6UnspecifiedAddress = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
244-
245-
#if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )
246-
247-
/*
248-
* Check if the packet is a loopback packet.
249-
*/
250-
static BaseType_t xIsIPv6Loopback( const IPHeader_IPv6_t * const pxIPv6Header );
251-
#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 */
252-
253240
/**
254241
* @brief Get the group ID and stored into IPv6_Address_t.
255242
*
@@ -270,34 +257,60 @@ static void xGetIPv6MulticastGroupID( const IPv6_Address_t * pxIPv6Address,
270257

271258
/*-----------------------------------------------------------*/
272259

260+
/**
261+
* @brief Check if the IP-address is an IPv6 loopback address.
262+
*
263+
* @param[in] pxAddress The IP-address being checked.
264+
*
265+
* @return pdTRUE if the IP-address is a loopback address or else, pdFALSE.
266+
*/
267+
BaseType_t xIsIPv6Loopback( const IPv6_Address_t * pxAddress )
268+
{
269+
BaseType_t xReturn = pdFALSE;
270+
271+
if( memcmp( pxAddress->ucBytes, FreeRTOS_in6addr_loopback.ucBytes, ipSIZE_OF_IPv6_ADDRESS ) == 0 )
272+
{
273+
xReturn = pdTRUE;
274+
}
275+
276+
return xReturn;
277+
}
278+
273279
#if ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )
274280

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

291298
/* Allow loopback packets from this node itself only. */
292-
if( ( pxEndPoint != NULL ) &&
293-
( memcmp( pxIPv6Header->xDestinationAddress.ucBytes, FreeRTOS_in6addr_loopback.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) &&
294-
( memcmp( pxIPv6Header->xSourceAddress.ucBytes, pxEndPoint->ipv6_settings.xIPAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
299+
if( pxEndPoint != NULL )
295300
{
296-
xReturn = pdTRUE;
301+
BaseType_t x1 = ( xIsIPv6Loopback( &( pxIPv6Header->xDestinationAddress ) ) != 0 ) ? pdTRUE : pdFALSE;
302+
BaseType_t x2 = ( xIsIPv6Loopback( &( pxIPv6Header->xSourceAddress ) ) != 0 ) ? pdTRUE : pdFALSE;
303+
304+
if( x1 != x2 )
305+
{
306+
/* Either source or the destination address is a loopback address. */
307+
xReturn = pdTRUE;
308+
}
297309
}
298310

299311
return xReturn;
300312
}
313+
301314
#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 */
302315

303316

@@ -332,7 +345,7 @@ BaseType_t xIsIPv6AllowedMulticast( const IPv6_Address_t * pxIPAddress )
332345
* - ..
333346
* - 0xFF0F:: */
334347
else if( ( IPv6MC_GET_FLAGS_VALUE( pxIPAddress ) == 0U ) &&
335-
( memcmp( xGroupIDAddress.ucBytes, xIPv6UnspecifiedAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
348+
( memcmp( xGroupIDAddress.ucBytes, FreeRTOS_in6addr_any.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
336349
{
337350
xReturn = pdFALSE;
338351
}
@@ -462,8 +475,8 @@ eFrameProcessingResult_t prvAllowIPPacketIPv6( const IPHeader_IPv6_t * const pxI
462475

463476
/* Drop if packet has unspecified IPv6 address (defined in RFC4291 - sec 2.5.2)
464477
* either in source or destination address. */
465-
if( ( memcmp( pxDestinationIPAddress->ucBytes, xIPv6UnspecifiedAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) ||
466-
( memcmp( pxSourceIPAddress->ucBytes, xIPv6UnspecifiedAddress.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
478+
if( ( memcmp( pxDestinationIPAddress->ucBytes, FreeRTOS_in6addr_any.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) ||
479+
( memcmp( pxSourceIPAddress->ucBytes, FreeRTOS_in6addr_any.ucBytes, sizeof( IPv6_Address_t ) ) == 0 ) )
467480
{
468481
xHasUnspecifiedAddress = pdTRUE;
469482
}
@@ -476,10 +489,9 @@ eFrameProcessingResult_t prvAllowIPPacketIPv6( const IPHeader_IPv6_t * const pxI
476489
eReturn = eProcessBuffer;
477490
}
478491
/* Is it the legal multicast address? */
479-
else if( ( xHasUnspecifiedAddress == pdFALSE ) &&
492+
else if( ( ( xHasUnspecifiedAddress == pdFALSE ) &&
493+
( xBadIPv6Loopback( pxIPv6Header ) == pdFALSE ) ) &&
480494
( ( xIsIPv6AllowedMulticast( pxDestinationIPAddress ) != pdFALSE ) ||
481-
/* Is it loopback address sent from this node? */
482-
( xIsIPv6Loopback( pxIPv6Header ) != pdFALSE ) ||
483495
/* Or (during DHCP negotiation) we have no IP-address yet? */
484496
( FreeRTOS_IsNetworkUp() == 0 ) ) )
485497
{

source/FreeRTOS_ND.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,8 @@
12541254

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

12591260
if( uxPrefixLength >= 8U )
12601261
{

0 commit comments

Comments
 (0)