Skip to content
Open
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
16 changes: 8 additions & 8 deletions source/FreeRTOS_ND.c
Original file line number Diff line number Diff line change
Expand Up @@ -1260,21 +1260,22 @@
* @param[out] pxIPAddress The location where the new IPv6 address will be stored.
* @param[in] pxPrefix The prefix to be used.
* @param[in] uxPrefixLength The length of the prefix.
* @param[in] xDoRandom A non-zero value if the bits after the prefix should have a random value.
* @param[in] pxHost: Host part of the address. It will be filled with
* a random value if NULL.
*
* @return pdPASS if the operation was successful. Or pdFAIL in case xApplicationGetRandomNumber()
* returned an error.
*/
BaseType_t FreeRTOS_CreateIPv6Address( IPv6_Address_t * pxIPAddress,
const IPv6_Address_t * pxPrefix,
size_t uxPrefixLength,
BaseType_t xDoRandom )
const IPv6_Address_t * pxHost )
{
uint32_t pulRandom[ 4 ];
uint32_t pulRandom[ ipSIZE_OF_IPv6_ADDRESS / sizeof( uint32_t ) ];
uint8_t * pucSource;
BaseType_t xIndex, xResult = pdPASS;

if( xDoRandom != pdFALSE )
if( pxHost == NULL )
{
/* Create an IP-address, based on a net prefix and a
* random host address.
Expand All @@ -1292,7 +1293,7 @@
}
else
{
( void ) memset( pulRandom, 0, sizeof( pulRandom ) );
( void ) memcpy( pulRandom, pxHost->ucBytes, ipSIZE_OF_IPv6_ADDRESS );
}

if( xResult == pdPASS )
Expand All @@ -1317,14 +1318,13 @@
uint8_t ucNetMask = ( uint8_t ) ~( uxHostMask );

pxIPAddress->ucBytes[ uxIndex ] &= ucNetMask;
pxIPAddress->ucBytes[ uxIndex ] |= ( pucSource[ 0 ] & ( ( uint8_t ) uxHostMask ) );
pucSource = &( pucSource[ 1 ] );
pxIPAddress->ucBytes[ uxIndex ] |= ( pucSource[ uxIndex ] & ( ( uint8_t ) uxHostMask ) );
uxIndex++;
}

if( uxIndex < ipSIZE_OF_IPv6_ADDRESS )
{
( void ) memcpy( &( pxIPAddress->ucBytes[ uxIndex ] ), pucSource, ipSIZE_OF_IPv6_ADDRESS - uxIndex );
( void ) memcpy( &( pxIPAddress->ucBytes[ uxIndex ] ), &pucSource[ uxIndex ], ipSIZE_OF_IPv6_ADDRESS - uxIndex );
}
}

Expand Down
39 changes: 36 additions & 3 deletions source/FreeRTOS_RA.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@
pxEndPoint->xRAData.bits.bRouterReplied = pdTRUE_UNSIGNED;
pxEndPoint->xRAData.uxRetryCount = 0U;
pxEndPoint->xRAData.ulPreferredLifeTime = FreeRTOS_ntohl( pxPrefixOption->ulPreferredLifeTime );
/* Force taking a new random IP-address. */
/* Force taking a new IP-address. */
pxEndPoint->xRAData.bits.bIPAddressInUse = pdTRUE_UNSIGNED;
pxEndPoint->xRAData.eRAState = eRAStateIPTest;
vRAProcess( pdFALSE, pxEndPoint );
Expand Down Expand Up @@ -521,6 +521,29 @@

return uxNewReloadTime;
}

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

/**
* @brief Assign an EUI64 address based on MAC address
*
* @param[out] pxIPAddress The assigned IPv6 address.
* @param[in] pxMACAddress The MAC address of the interface.
*/
static void vRAProcessAssignEUI64( IPv6_Address_t * pxIPAddress,
const MACAddress_t * pxMACAddress )
{
memset( pxIPAddress, 0, sizeof( IPv6_Address_t ) );
pxIPAddress->ucBytes[ 8 ] = pxMACAddress->ucBytes[ 0 ] ^ 0x2;
pxIPAddress->ucBytes[ 9 ] = pxMACAddress->ucBytes[ 1 ];
pxIPAddress->ucBytes[ 10 ] = pxMACAddress->ucBytes[ 2 ];
pxIPAddress->ucBytes[ 11 ] = 0xff;
pxIPAddress->ucBytes[ 12 ] = 0xfe;
pxIPAddress->ucBytes[ 13 ] = pxMACAddress->ucBytes[ 3 ];
pxIPAddress->ucBytes[ 14 ] = pxMACAddress->ucBytes[ 4 ];
pxIPAddress->ucBytes[ 15 ] = pxMACAddress->ucBytes[ 5 ];
}

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

/**
Expand Down Expand Up @@ -571,15 +594,25 @@
{
size_t uxNeededSize;
NetworkBufferDescriptor_t * pxNetworkBuffer;
IPv6_Address_t xIPAddress;
IPv6_Address_t * pxIPAddress;

pxIPAddress = NULL;

/* Get an IP-address, using the network prefix and a random host address. */
if( pxEndPoint->xRAData.bits.bIPAddressInUse != 0U )
{
pxEndPoint->xRAData.bits.bIPAddressInUse = pdFALSE_UNSIGNED;

( void ) FreeRTOS_CreateIPv6Address( &pxEndPoint->ipv6_settings.xIPAddress, &pxEndPoint->ipv6_settings.xPrefix, pxEndPoint->ipv6_settings.uxPrefixLength, pdTRUE );
if( pxEndPoint->bits.bWantEUI64 != pdFALSE_UNSIGNED )
{
pxIPAddress = &xIPAddress;
vRAProcessAssignEUI64( pxIPAddress, &pxEndPoint->xMACAddress );
}

( void ) FreeRTOS_CreateIPv6Address( &pxEndPoint->ipv6_settings.xIPAddress, &pxEndPoint->ipv6_settings.xPrefix, pxEndPoint->ipv6_settings.uxPrefixLength, pxIPAddress );

FreeRTOS_printf( ( "RA: Creating a random IP-address\n" ) );
FreeRTOS_printf( ( "RA: Creating an IP-address\n" ) );
}

FreeRTOS_printf( ( "RA: Neighbour solicitation for %pip\n", ( void * ) pxEndPoint->ipv6_settings.xIPAddress.ucBytes ) );
Expand Down
8 changes: 4 additions & 4 deletions source/include/FreeRTOS_ND.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,14 @@
#endif

/**
* @brief Create an IPv16 address, based on a prefix.
* @brief Create an IPv6 address, based on a prefix.
*
* @param[out] pxIPAddress: The location where the new IPv6 address
* will be stored.
* @param[in] pxPrefix: The prefix to be used.
* @param[in] uxPrefixLength: The length of the prefix.
* @param[in] xDoRandom: A non-zero value if the bits after the
* prefix should have a random value.
* @param[in] pxHost: Host part of the address. It will be filled with
* a random value if NULL.
*
* @return pdPASS if the operation was successful. Or pdFAIL in
* case xApplicationGetRandomNumber()
Expand All @@ -176,7 +176,7 @@
BaseType_t FreeRTOS_CreateIPv6Address( IPv6_Address_t * pxIPAddress,
const IPv6_Address_t * pxPrefix,
size_t uxPrefixLength,
BaseType_t xDoRandom );
const IPv6_Address_t * pxHost );

/* Receive a Neighbour Advertisement. */

Expand Down
1 change: 1 addition & 0 deletions source/include/FreeRTOS_Routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
#endif /* ipconfigUSE_DHCP */
#if ( ipconfigUSE_RA != 0 )
bWantRA : 1, /**< This end-point wants to use RA/SLAAC to obtain an IP-address. */
bWantEUI64 : 1, /**< This end-point wants to use EUI64 for IP-address generation. */
#endif /* ipconfigUSE_RA */
bIPv6 : 1, /**< This end-point has an IP-address of type IPv6. */
#if ( ipconfigUSE_NETWORK_EVENT_HOOK != 0 )
Expand Down
36 changes: 18 additions & 18 deletions test/unit-test/FreeRTOS_ND/FreeRTOS_ND_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1834,12 +1834,12 @@ void test_FreeRTOS_OutputAdvertiseIPv6_HappyPath( void )
*/
void test_FreeRTOS_CreateIPv6Address_RandomFail( void )
{
IPv6_Address_t xIPAddress, xPrefix = { 0 };
BaseType_t xDoRandom = pdTRUE, xReturn;
IPv6_Address_t xIPAddress, xPrefix = { 0 }, * pxHost = NULL;
BaseType_t xReturn;

xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdFALSE );

xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, sizeof( xPrefix ), xDoRandom );
xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, sizeof( xPrefix ), pxHost );

TEST_ASSERT_EQUAL( xReturn, pdFAIL );
}
Expand All @@ -1851,30 +1851,30 @@ void test_FreeRTOS_CreateIPv6Address_RandomFail( void )
*/
void test_FreeRTOS_CreateIPv6Address_Assert1( void )
{
IPv6_Address_t xIPAddress, xPrefix = { 0 };
BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;
IPv6_Address_t xIPAddress, xPrefix = { 0 }, * pxHost = NULL;
BaseType_t xReturn, xIndex;

for( xIndex = 0; xIndex < 4; xIndex++ )
{
xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
}

catch_assert( FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, 0, xDoRandom ) );
catch_assert( FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, 0, pxHost ) );
}

/**
* @brief Create an IPv6 address, based on a prefix.
* with the bits after the prefix having random value
* but incorrect prefix length and xDoRandom is 0.
* with the bits after the prefix having a specified value
* but incorrect prefix length.
*/
void test_FreeRTOS_CreateIPv6Address_Assert2( void )
{
IPv6_Address_t xIPAddress, xPrefix;
IPv6_Address_t xIPAddress, xPrefix, xHost = { 0 };
/* The maximum allowed prefix length was increased to 128 because of the loopback address. */
size_t uxPrefixLength = 8U * ipSIZE_OF_IPv6_ADDRESS + 1;
BaseType_t xDoRandom = pdFALSE, xReturn, xIndex;
BaseType_t xReturn, xIndex;

catch_assert( FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom ) );
catch_assert( FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, &xHost ) );
}

/**
Expand All @@ -1883,16 +1883,16 @@ void test_FreeRTOS_CreateIPv6Address_Assert2( void )
*/
void test_FreeRTOS_CreateIPv6Address_Pass1( void )
{
IPv6_Address_t xIPAddress, xPrefix;
IPv6_Address_t xIPAddress, xPrefix, * pxHost = NULL;
size_t uxPrefixLength = 8U;
BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;
BaseType_t xReturn, xIndex;

for( xIndex = 0; xIndex < 4; xIndex++ )
{
xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
}

xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom );
xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, pxHost );

TEST_ASSERT_EQUAL( xReturn, pdPASS );
}
Expand All @@ -1904,7 +1904,7 @@ void test_FreeRTOS_CreateIPv6Address_Pass1( void )
*/
void test_FreeRTOS_CreateIPv6Address_Pass2( void )
{
IPv6_Address_t xIPAddress, xPrefix;
IPv6_Address_t xIPAddress, xPrefix, * pxHost = NULL;
size_t uxPrefixLength = 7;
BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;

Expand All @@ -1913,7 +1913,7 @@ void test_FreeRTOS_CreateIPv6Address_Pass2( void )
xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
}

xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom );
xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, pxHost );

TEST_ASSERT_EQUAL( xReturn, pdPASS );
}
Expand All @@ -1925,7 +1925,7 @@ void test_FreeRTOS_CreateIPv6Address_Pass2( void )
*/
void test_FreeRTOS_CreateIPv6Address_Pass3( void )
{
IPv6_Address_t xIPAddress, xPrefix;
IPv6_Address_t xIPAddress, xPrefix, * pxHost = NULL;
size_t uxPrefixLength = 128;
BaseType_t xDoRandom = pdTRUE, xReturn, xIndex;

Expand All @@ -1934,7 +1934,7 @@ void test_FreeRTOS_CreateIPv6Address_Pass3( void )
xApplicationGetRandomNumber_ExpectAnyArgsAndReturn( pdTRUE );
}

xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, xDoRandom );
xReturn = FreeRTOS_CreateIPv6Address( &xIPAddress, &xPrefix, uxPrefixLength, pxHost );

TEST_ASSERT_EQUAL( xReturn, pdPASS );
}
Expand Down
6 changes: 3 additions & 3 deletions test/unit-test/FreeRTOS_RA/FreeRTOS_RA_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ eResolutionLookupResult_t eNDGetCacheEntry( IPv6_Address_t * pxIPAddress,
* will be stored.
* @param[in] pxPrefix: The prefix to be used.
* @param[in] uxPrefixLength: The length of the prefix.
* @param[in] xDoRandom: A non-zero value if the bits after the
* prefix should have a random value.
* @param[in] pxHost: Host part of the address. It will be filled with
* a random value if NULL.
*
* @return pdPASS if the operation was successful. Or pdFAIL in
* case xApplicationGetRandomNumber()
Expand All @@ -55,7 +55,7 @@ eResolutionLookupResult_t eNDGetCacheEntry( IPv6_Address_t * pxIPAddress,
BaseType_t FreeRTOS_CreateIPv6Address( IPv6_Address_t * pxIPAddress,
const IPv6_Address_t * pxPrefix,
size_t uxPrefixLength,
BaseType_t xDoRandom )
const IPv6_Address_t * pxHost )
{
}

Expand Down
50 changes: 50 additions & 0 deletions test/unit-test/FreeRTOS_RA/FreeRTOS_RA_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,56 @@ void test_vReceiveRA_vRAProcess( void )
TEST_ASSERT_EQUAL( eRAStateIPWait, pxEndPoint->xRAData.eRAState );
}

/**
* @brief This function verify vReceiveRA success case for an EUI64 address.
*/
void test_vReceiveRA_vRAProcess_EUI64( void )
{
NetworkBufferDescriptor_t * pxNetworkBuffer, xNetworkBuffer;
EthernetPacketICMPv6RouterAdvertisementPrefixOption_t xICMPPacket;
NetworkInterface_t xInterface;
NetworkEndPoint_t xEndPoint, * pxEndPoint = &xEndPoint;
ICMPPrefixOption_IPv6_t * pxPrefixOption;
ICMPRouterAdvertisement_IPv6_t * pxAdvertisement;

memset( &xNetworkBuffer, 0, sizeof( NetworkBufferDescriptor_t ) );
memset( &xICMPPacket, 0, sizeof( xICMPPacket ) );
memset( &xInterface, 0, sizeof( NetworkInterface_t ) );
memset( &xEndPoint, 0, sizeof( NetworkEndPoint_t ) );

pxNetworkBuffer = &xNetworkBuffer;
pxNetworkBuffer->pucEthernetBuffer = ( uint8_t * ) &xICMPPacket;
pxNetworkBuffer->pxInterface = &xInterface;
pxNetworkBuffer->xDataLength = raHeaderBytesRA + raPrefixOptionlen;
pxAdvertisement = &xICMPPacket.xAdvertisement;
pxAdvertisement->usLifetime = pdTRUE_UNSIGNED;

pxPrefixOption = &xICMPPacket.xPrefixOption;
pxPrefixOption->ucType = ndICMP_PREFIX_INFORMATION;
/* Only 1 option */
pxPrefixOption->ucLength = 1;

pxEndPoint->bits.bWantRA = pdTRUE_UNSIGNED;
pxEndPoint->bits.bWantEUI64 = pdTRUE_UNSIGNED;
pxEndPoint->xRAData.eRAState = eRAStateWait;

FreeRTOS_FirstEndPoint_ExpectAnyArgsAndReturn( pxEndPoint );
FreeRTOS_NextEndPoint_IgnoreAndReturn( NULL );

pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
vDHCP_RATimerReload_ExpectAnyArgs();

vReceiveRA( pxNetworkBuffer );


TEST_ASSERT_EQUAL( pxEndPoint->ipv6_settings.uxPrefixLength, pxPrefixOption->ucPrefixLength );
TEST_ASSERT_EQUAL( pdTRUE_UNSIGNED, pxEndPoint->xRAData.bits.bRouterReplied );
TEST_ASSERT_EQUAL( 0, pxEndPoint->xRAData.uxRetryCount );
TEST_ASSERT_EQUAL( FreeRTOS_ntohl( pxPrefixOption->ulPreferredLifeTime ), pxEndPoint->xRAData.ulPreferredLifeTime );
TEST_ASSERT_EQUAL( pdFALSE_UNSIGNED, pxEndPoint->xRAData.bits.bIPAddressInUse );
TEST_ASSERT_EQUAL( eRAStateIPWait, pxEndPoint->xRAData.eRAState );
}

/**
* @brief This function verify RA state machine
* with RA NULL endpoint.
Expand Down
Loading