mirror of
https://github.com/FreeRTOS/FreeRTOS-Plus-TCP
synced 2025-10-24 12:02:37 +08:00
ARP changes to support IPv6 (#608)
The changes includes generic ARP and ARP endpoint changes to support IPv6.
This commit is contained in:
@@ -43,7 +43,6 @@
|
|||||||
/* FreeRTOS+TCP includes. */
|
/* FreeRTOS+TCP includes. */
|
||||||
#include "FreeRTOS_IP.h"
|
#include "FreeRTOS_IP.h"
|
||||||
#include "FreeRTOS_IP_Timers.h"
|
#include "FreeRTOS_IP_Timers.h"
|
||||||
#include "FreeRTOS_IP_Utils.h"
|
|
||||||
#include "FreeRTOS_Sockets.h"
|
#include "FreeRTOS_Sockets.h"
|
||||||
#include "FreeRTOS_IP_Private.h"
|
#include "FreeRTOS_IP_Private.h"
|
||||||
#include "FreeRTOS_ARP.h"
|
#include "FreeRTOS_ARP.h"
|
||||||
@@ -53,7 +52,6 @@
|
|||||||
#include "FreeRTOS_DNS.h"
|
#include "FreeRTOS_DNS.h"
|
||||||
#endif /* ipconfigUSE_LLMNR */
|
#endif /* ipconfigUSE_LLMNR */
|
||||||
#include "NetworkBufferManagement.h"
|
#include "NetworkBufferManagement.h"
|
||||||
#include "FreeRTOS_Routing.h"
|
|
||||||
#include "NetworkInterface.h"
|
#include "NetworkInterface.h"
|
||||||
#include "FreeRTOS_Routing.h"
|
#include "FreeRTOS_Routing.h"
|
||||||
#include "FreeRTOS_ND.h"
|
#include "FreeRTOS_ND.h"
|
||||||
@@ -87,11 +85,13 @@
|
|||||||
* Lookup an MAC address in the ARP cache from the IP address.
|
* Lookup an MAC address in the ARP cache from the IP address.
|
||||||
*/
|
*/
|
||||||
static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup,
|
static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup,
|
||||||
MACAddress_t * const pxMACAddress );
|
MACAddress_t * const pxMACAddress,
|
||||||
|
NetworkEndPoint_t ** ppxEndPoint );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void vProcessARPPacketReply( const ARPPacket_t * pxARPFrame,
|
static void vProcessARPPacketReply( const ARPPacket_t * pxARPFrame,
|
||||||
|
NetworkEndPoint_t * pxTargetEndPoint,
|
||||||
uint32_t ulSenderProtocolAddress );
|
uint32_t ulSenderProtocolAddress );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@@ -132,6 +132,11 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
/* memcpy() helper variables for MISRA Rule 21.15 compliance*/
|
/* memcpy() helper variables for MISRA Rule 21.15 compliance*/
|
||||||
const void * pvCopySource;
|
const void * pvCopySource;
|
||||||
void * pvCopyDest;
|
void * pvCopyDest;
|
||||||
|
NetworkEndPoint_t * pxTargetEndPoint = pxNetworkBuffer->pxEndPoint;
|
||||||
|
|
||||||
|
#if ( ipconfigARP_USE_CLASH_DETECTION != 0 )
|
||||||
|
NetworkEndPoint_t * pxSourceEndPoint;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Next defensive request must not be sent for arpIP_CLASH_RESET_TIMEOUT_MS
|
/* Next defensive request must not be sent for arpIP_CLASH_RESET_TIMEOUT_MS
|
||||||
* period. */
|
* period. */
|
||||||
@@ -186,6 +191,10 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ( ipconfigARP_USE_CLASH_DETECTION != 0 )
|
||||||
|
pxSourceEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulSenderProtocolAddress, 2 ); /* Clash detection. */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check whether the lowest bit of the highest byte is 1 to check for
|
/* Check whether the lowest bit of the highest byte is 1 to check for
|
||||||
* multicast address or even a broadcast address (FF:FF:FF:FF:FF:FF). */
|
* multicast address or even a broadcast address (FF:FF:FF:FF:FF:FF). */
|
||||||
if( ( pxARPHeader->xSenderHardwareAddress.ucBytes[ 0 ] & 0x01U ) == 0x01U )
|
if( ( pxARPHeader->xSenderHardwareAddress.ucBytes[ 0 ] & 0x01U ) == 0x01U )
|
||||||
@@ -234,9 +243,12 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
/* Process received ARP frame to see if there is a clash. */
|
/* Process received ARP frame to see if there is a clash. */
|
||||||
#if ( ipconfigARP_USE_CLASH_DETECTION != 0 )
|
#if ( ipconfigARP_USE_CLASH_DETECTION != 0 )
|
||||||
{
|
{
|
||||||
xARPHadIPClash = pdTRUE;
|
if( pxSourceEndPoint != NULL )
|
||||||
/* Remember the MAC-address of the other device which has the same IP-address. */
|
{
|
||||||
( void ) memcpy( xARPClashMacAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( xARPClashMacAddress.ucBytes ) );
|
xARPHadIPClash = pdTRUE;
|
||||||
|
/* Remember the MAC-address of the other device which has the same IP-address. */
|
||||||
|
( void ) memcpy( xARPClashMacAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( xARPClashMacAddress.ucBytes ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* ipconfigARP_USE_CLASH_DETECTION */
|
#endif /* ipconfigARP_USE_CLASH_DETECTION */
|
||||||
|
|
||||||
@@ -247,7 +259,8 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
|
|
||||||
/* Don't do anything if the local IP address is zero because
|
/* Don't do anything if the local IP address is zero because
|
||||||
* that means a DHCP request has not completed. */
|
* that means a DHCP request has not completed. */
|
||||||
if( *ipLOCAL_IP_ADDRESS_POINTER != 0U )
|
//if( *ipLOCAL_IP_ADDRESS_POINTER != 0U )
|
||||||
|
if( ( pxTargetEndPoint != NULL ) && ( pxTargetEndPoint->bits.bEndPointUp != pdFALSE_UNSIGNED ) )
|
||||||
{
|
{
|
||||||
switch( pxARPHeader->usOperation )
|
switch( pxARPHeader->usOperation )
|
||||||
{
|
{
|
||||||
@@ -266,7 +279,7 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
/* The request is for the address of this node. Add the
|
/* The request is for the address of this node. Add the
|
||||||
* entry into the ARP cache, or refresh the entry if it
|
* entry into the ARP cache, or refresh the entry if it
|
||||||
* already exists. */
|
* already exists. */
|
||||||
vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
|
vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint );
|
||||||
|
|
||||||
/* Generate a reply payload in the same buffer. */
|
/* Generate a reply payload in the same buffer. */
|
||||||
pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY;
|
pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY;
|
||||||
@@ -289,6 +302,20 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
pvCopySource = ipLOCAL_IP_ADDRESS_POINTER;
|
pvCopySource = ipLOCAL_IP_ADDRESS_POINTER;
|
||||||
pvCopyDest = pxARPHeader->ucSenderProtocolAddress;
|
pvCopyDest = pxARPHeader->ucSenderProtocolAddress;
|
||||||
( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxARPHeader->ucSenderProtocolAddress ) );
|
( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxARPHeader->ucSenderProtocolAddress ) );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use helper variables for memcpy() to remain
|
||||||
|
* compliant with MISRA Rule 21.15. These should be
|
||||||
|
* optimized away.
|
||||||
|
*/
|
||||||
|
pvCopySource = pxTargetEndPoint->xMACAddress.ucBytes;
|
||||||
|
pvCopyDest = pxARPHeader->xSenderHardwareAddress.ucBytes;
|
||||||
|
( void ) memcpy( pvCopyDest, pvCopySource, sizeof( MACAddress_t ) );
|
||||||
|
|
||||||
|
pvCopySource = &( pxTargetEndPoint->ipv4_settings.ulIPAddress );
|
||||||
|
pvCopyDest = pxARPHeader->ucSenderProtocolAddress;
|
||||||
|
( void ) memcpy( pvCopyDest, pvCopySource, sizeof( pxARPHeader->ucSenderProtocolAddress ) );
|
||||||
|
|
||||||
eReturn = eReturnEthernetFrame;
|
eReturn = eReturnEthernetFrame;
|
||||||
}
|
}
|
||||||
@@ -296,7 +323,7 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ipARP_REPLY:
|
case ipARP_REPLY:
|
||||||
vProcessARPPacketReply( pxARPFrame, ulSenderProtocolAddress );
|
vProcessARPPacketReply( pxARPFrame, pxTargetEndPoint, ulSenderProtocolAddress );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -317,6 +344,7 @@ eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
|
|||||||
* @param[in] ulSenderProtocolAddress: The IPv4 address involved.
|
* @param[in] ulSenderProtocolAddress: The IPv4 address involved.
|
||||||
*/
|
*/
|
||||||
static void vProcessARPPacketReply( const ARPPacket_t * pxARPFrame,
|
static void vProcessARPPacketReply( const ARPPacket_t * pxARPFrame,
|
||||||
|
NetworkEndPoint_t * pxTargetEndPoint,
|
||||||
uint32_t ulSenderProtocolAddress )
|
uint32_t ulSenderProtocolAddress )
|
||||||
{
|
{
|
||||||
const ARPHeader_t * pxARPHeader = &( pxARPFrame->xARPHeader );
|
const ARPHeader_t * pxARPHeader = &( pxARPFrame->xARPHeader );
|
||||||
@@ -327,7 +355,7 @@ static void vProcessARPPacketReply( const ARPPacket_t * pxARPFrame,
|
|||||||
( xIsIPInARPCache( ulSenderProtocolAddress ) == pdTRUE ) )
|
( xIsIPInARPCache( ulSenderProtocolAddress ) == pdTRUE ) )
|
||||||
{
|
{
|
||||||
iptracePROCESSING_RECEIVED_ARP_REPLY( ulTargetProtocolAddress );
|
iptracePROCESSING_RECEIVED_ARP_REPLY( ulTargetProtocolAddress );
|
||||||
vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
|
vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress, pxTargetEndPoint );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxARPWaitingNetworkBuffer != NULL )
|
if( pxARPWaitingNetworkBuffer != NULL )
|
||||||
@@ -474,7 +502,8 @@ BaseType_t xCheckRequiresARPResolution( const NetworkBufferDescriptor_t * pxNetw
|
|||||||
* is being updated.
|
* is being updated.
|
||||||
*/
|
*/
|
||||||
void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
|
void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
|
||||||
const uint32_t ulIPAddress )
|
const uint32_t ulIPAddress,
|
||||||
|
struct xNetworkEndPoint * pxEndPoint )
|
||||||
{
|
{
|
||||||
BaseType_t x = 0;
|
BaseType_t x = 0;
|
||||||
BaseType_t xIpEntry = -1;
|
BaseType_t xIpEntry = -1;
|
||||||
@@ -542,6 +571,7 @@ void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
|
|||||||
* function by setting 'xAllDone' to pdTRUE. */
|
* function by setting 'xAllDone' to pdTRUE. */
|
||||||
xARPCache[ x ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
|
xARPCache[ x ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
|
||||||
xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
|
xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
|
||||||
|
xARPCache[ x ].pxEndPoint = pxEndPoint;
|
||||||
xAllDone = pdTRUE;
|
xAllDone = pdTRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -630,6 +660,7 @@ void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
|
|||||||
/* And this entry does not need immediate attention */
|
/* And this entry does not need immediate attention */
|
||||||
xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
|
xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
|
||||||
xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdTRUE;
|
xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdTRUE;
|
||||||
|
xARPCache[ xLocation.xUseEntry ].pxEndPoint = pxEndPoint;
|
||||||
}
|
}
|
||||||
else if( xIpEntry < 0 )
|
else if( xIpEntry < 0 )
|
||||||
{
|
{
|
||||||
@@ -656,7 +687,8 @@ void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
|
|||||||
* @return Either eARPCacheMiss or eARPCacheHit.
|
* @return Either eARPCacheMiss or eARPCacheHit.
|
||||||
*/
|
*/
|
||||||
eARPLookupResult_t eARPGetCacheEntryByMac( const MACAddress_t * const pxMACAddress,
|
eARPLookupResult_t eARPGetCacheEntryByMac( const MACAddress_t * const pxMACAddress,
|
||||||
uint32_t * pulIPAddress )
|
uint32_t * pulIPAddress,
|
||||||
|
struct xNetworkInterface ** ppxInterface )
|
||||||
{
|
{
|
||||||
BaseType_t x;
|
BaseType_t x;
|
||||||
eARPLookupResult_t eReturn = eARPCacheMiss;
|
eARPLookupResult_t eReturn = eARPCacheMiss;
|
||||||
@@ -664,6 +696,11 @@ void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
|
|||||||
configASSERT( pxMACAddress != NULL );
|
configASSERT( pxMACAddress != NULL );
|
||||||
configASSERT( pulIPAddress != NULL );
|
configASSERT( pulIPAddress != NULL );
|
||||||
|
|
||||||
|
if( ppxInterface != NULL )
|
||||||
|
{
|
||||||
|
*( ppxInterface ) = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Loop through each entry in the ARP cache. */
|
/* Loop through each entry in the ARP cache. */
|
||||||
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||||
{
|
{
|
||||||
@@ -672,6 +709,13 @@ void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress,
|
|||||||
if( memcmp( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
|
if( memcmp( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
|
||||||
{
|
{
|
||||||
*pulIPAddress = xARPCache[ x ].ulIPAddress;
|
*pulIPAddress = xARPCache[ x ].ulIPAddress;
|
||||||
|
|
||||||
|
if( ( ppxInterface != NULL ) &&
|
||||||
|
( xARPCache[ x ].pxEndPoint != NULL ) )
|
||||||
|
{
|
||||||
|
*( ppxInterface ) = xARPCache[ x ].pxEndPoint->pxNetworkInterface;
|
||||||
|
}
|
||||||
|
|
||||||
eReturn = eARPCacheHit;
|
eReturn = eARPCacheHit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -733,7 +777,6 @@ eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( ( *pulIPAddress == ipBROADCAST_IP_ADDRESS ) || /* Is it the general broadcast address 255.255.255.255? */
|
else if( ( *pulIPAddress == ipBROADCAST_IP_ADDRESS ) || /* Is it the general broadcast address 255.255.255.255? */
|
||||||
( *pulIPAddress == xNetworkAddressing.ulBroadcastAddress ) ) /* Or a local broadcast address, eg 192.168.1.255? */
|
( *pulIPAddress == xNetworkAddressing.ulBroadcastAddress ) ) /* Or a local broadcast address, eg 192.168.1.255? */
|
||||||
@@ -843,12 +886,14 @@ eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress,
|
|||||||
* @param[out] pxMACAddress: A pointer to MACAddress_t variable where, if there
|
* @param[out] pxMACAddress: A pointer to MACAddress_t variable where, if there
|
||||||
* is an ARP cache hit, the MAC address corresponding to
|
* is an ARP cache hit, the MAC address corresponding to
|
||||||
* the IP address will be stored.
|
* the IP address will be stored.
|
||||||
|
* @param[in,out] ppxEndPoint: a pointer to the end-point will be stored.
|
||||||
*
|
*
|
||||||
* @return When the IP-address is found: eARPCacheHit, when not found: eARPCacheMiss,
|
* @return When the IP-address is found: eARPCacheHit, when not found: eARPCacheMiss,
|
||||||
* and when waiting for a ARP reply: eCantSendPacket.
|
* and when waiting for a ARP reply: eCantSendPacket.
|
||||||
*/
|
*/
|
||||||
static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup,
|
static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup,
|
||||||
MACAddress_t * const pxMACAddress )
|
MACAddress_t * const pxMACAddress,
|
||||||
|
NetworkEndPoint_t ** ppxEndPoint )
|
||||||
{
|
{
|
||||||
BaseType_t x;
|
BaseType_t x;
|
||||||
eARPLookupResult_t eReturn = eARPCacheMiss;
|
eARPLookupResult_t eReturn = eARPCacheMiss;
|
||||||
@@ -870,6 +915,8 @@ static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup,
|
|||||||
{
|
{
|
||||||
/* A valid entry was found. */
|
/* A valid entry was found. */
|
||||||
( void ) memcpy( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
|
( void ) memcpy( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
|
||||||
|
/* ppxEndPoint != NULL was tested in the only caller eARPGetCacheEntry(). */
|
||||||
|
*( ppxEndPoint ) = xARPCache[ x ].pxEndPoint;
|
||||||
eReturn = eARPCacheHit;
|
eReturn = eARPCacheHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,50 +1034,67 @@ void vARPSendGratuitous( void )
|
|||||||
void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress )
|
void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress )
|
||||||
{
|
{
|
||||||
NetworkBufferDescriptor_t * pxNetworkBuffer;
|
NetworkBufferDescriptor_t * pxNetworkBuffer;
|
||||||
|
NetworkEndPoint_t * pxEndPoint;
|
||||||
|
NetworkInterface_t * pxInterface;
|
||||||
|
|
||||||
/* This is called from the context of the IP event task, so a block time
|
for( pxInterface = FreeRTOS_FirstNetworkInterface();
|
||||||
* must not be used. */
|
pxInterface != NULL;
|
||||||
pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( ARPPacket_t ), ( TickType_t ) 0U );
|
pxInterface = FreeRTOS_NextNetworkInterface( pxInterface ) )
|
||||||
|
|
||||||
if( pxNetworkBuffer != NULL )
|
|
||||||
{
|
{
|
||||||
pxNetworkBuffer->xIPAddress.xIP_IPv4 = ulIPAddress;
|
pxEndPoint = FreeRTOS_FindEndPointOnIP_IPv4( ulIPAddress, 25 );
|
||||||
vARPGenerateRequestPacket( pxNetworkBuffer );
|
|
||||||
|
|
||||||
#if ( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 )
|
if( pxEndPoint == NULL )
|
||||||
{
|
|
||||||
if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
|
|
||||||
{
|
|
||||||
BaseType_t xIndex;
|
|
||||||
|
|
||||||
for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
|
|
||||||
{
|
|
||||||
pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0U;
|
|
||||||
}
|
|
||||||
|
|
||||||
pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* if( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 ) */
|
|
||||||
|
|
||||||
if( xIsCallingFromIPTask() != pdFALSE )
|
|
||||||
{
|
{
|
||||||
iptraceNETWORK_INTERFACE_OUTPUT( pxNetworkBuffer->xDataLength, pxNetworkBuffer->pucEthernetBuffer );
|
pxEndPoint = FreeRTOS_InterfaceEndPointOnNetMask( pxInterface, ulIPAddress, 26 );
|
||||||
/* Only the IP-task is allowed to call this function directly. */
|
|
||||||
( void ) xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if( pxEndPoint != NULL )
|
||||||
{
|
{
|
||||||
IPStackEvent_t xSendEvent;
|
/* This is called from the context of the IP event task, so a block time
|
||||||
|
* must not be used. */
|
||||||
|
pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( ARPPacket_t ), ( TickType_t ) 0U );
|
||||||
|
|
||||||
/* Send a message to the IP-task to send this ARP packet. */
|
if( pxNetworkBuffer != NULL )
|
||||||
xSendEvent.eEventType = eNetworkTxEvent;
|
|
||||||
xSendEvent.pvData = pxNetworkBuffer;
|
|
||||||
|
|
||||||
if( xSendEventStructToIPTask( &xSendEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
|
|
||||||
{
|
{
|
||||||
/* Failed to send the message, so release the network buffer. */
|
pxNetworkBuffer->xIPAddress.xIP_IPv4 = ulIPAddress;
|
||||||
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
|
vARPGenerateRequestPacket( pxNetworkBuffer );
|
||||||
|
|
||||||
|
#if ( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 )
|
||||||
|
{
|
||||||
|
if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
|
||||||
|
{
|
||||||
|
BaseType_t xIndex;
|
||||||
|
|
||||||
|
for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
|
||||||
|
{
|
||||||
|
pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* if( ipconfigETHERNET_MINIMUM_PACKET_BYTES > 0 ) */
|
||||||
|
|
||||||
|
if( xIsCallingFromIPTask() != pdFALSE )
|
||||||
|
{
|
||||||
|
iptraceNETWORK_INTERFACE_OUTPUT( pxNetworkBuffer->xDataLength, pxNetworkBuffer->pucEthernetBuffer );
|
||||||
|
/* Only the IP-task is allowed to call this function directly. */
|
||||||
|
( void ) xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IPStackEvent_t xSendEvent;
|
||||||
|
|
||||||
|
/* Send a message to the IP-task to send this ARP packet. */
|
||||||
|
xSendEvent.eEventType = eNetworkTxEvent;
|
||||||
|
xSendEvent.pvData = pxNetworkBuffer;
|
||||||
|
|
||||||
|
if( xSendEventStructToIPTask( &xSendEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
|
||||||
|
{
|
||||||
|
/* Failed to send the message, so release the network buffer. */
|
||||||
|
vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1054,13 +1118,14 @@ BaseType_t xARPWaitResolution( uint32_t ulIPAddress,
|
|||||||
TimeOut_t xTimeOut;
|
TimeOut_t xTimeOut;
|
||||||
MACAddress_t xMACAddress;
|
MACAddress_t xMACAddress;
|
||||||
eARPLookupResult_t xLookupResult;
|
eARPLookupResult_t xLookupResult;
|
||||||
|
NetworkEndPoint_t * pxEndPoint;
|
||||||
size_t uxSendCount = ipconfigMAX_ARP_RETRANSMISSIONS;
|
size_t uxSendCount = ipconfigMAX_ARP_RETRANSMISSIONS;
|
||||||
uint32_t ulIPAddressCopy = ulIPAddress;
|
uint32_t ulIPAddressCopy = ulIPAddress;
|
||||||
|
|
||||||
/* The IP-task is not supposed to call this function. */
|
/* The IP-task is not supposed to call this function. */
|
||||||
configASSERT( xIsCallingFromIPTask() == pdFALSE );
|
configASSERT( xIsCallingFromIPTask() == pdFALSE );
|
||||||
|
|
||||||
xLookupResult = eARPGetCacheEntry( &( ulIPAddressCopy ), &( xMACAddress ) );
|
xLookupResult = eARPGetCacheEntry( &( ulIPAddressCopy ), &( xMACAddress ), &( pxEndPoint ) );
|
||||||
|
|
||||||
if( xLookupResult == eARPCacheMiss )
|
if( xLookupResult == eARPCacheMiss )
|
||||||
{
|
{
|
||||||
@@ -1075,7 +1140,7 @@ BaseType_t xARPWaitResolution( uint32_t ulIPAddress,
|
|||||||
|
|
||||||
vTaskDelay( uxSleepTime );
|
vTaskDelay( uxSleepTime );
|
||||||
|
|
||||||
xLookupResult = eARPGetCacheEntry( &( ulIPAddressCopy ), &( xMACAddress ) );
|
xLookupResult = eARPGetCacheEntry( &( ulIPAddressCopy ), &( xMACAddress ), &( pxEndPoint ) );
|
||||||
|
|
||||||
if( ( xTaskCheckForTimeOut( &( xTimeOut ), &( uxTicksToWait ) ) == pdTRUE ) ||
|
if( ( xTaskCheckForTimeOut( &( xTimeOut ), &( uxTicksToWait ) ) == pdTRUE ) ||
|
||||||
( xLookupResult != eARPCacheMiss ) )
|
( xLookupResult != eARPCacheMiss ) )
|
||||||
@@ -1183,10 +1248,27 @@ void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffe
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A call to this function will clear the ARP cache.
|
* @brief A call to this function will clear the ARP cache.
|
||||||
|
* @param[in] pxEndPoint: only clean entries with this end-point, or when NULL,
|
||||||
|
* clear the entire ARP cache.
|
||||||
*/
|
*/
|
||||||
void FreeRTOS_ClearARP( void )
|
void FreeRTOS_ClearARP( const struct xNetworkEndPoint * pxEndPoint )
|
||||||
{
|
{
|
||||||
( void ) memset( xARPCache, 0, sizeof( xARPCache ) );
|
if( pxEndPoint != NULL )
|
||||||
|
{
|
||||||
|
BaseType_t x;
|
||||||
|
|
||||||
|
for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
|
||||||
|
{
|
||||||
|
if( xARPCache[ x ].pxEndPoint == pxEndPoint )
|
||||||
|
{
|
||||||
|
( void ) memset( &( xARPCache[ x ] ), 0, sizeof( ARPCacheRow_t ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
( void ) memset( xARPCache, 0, sizeof( xARPCache ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -1217,7 +1299,12 @@ void FreeRTOS_ClearARP( void )
|
|||||||
|
|
||||||
if( pxIPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
|
if( pxIPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
|
||||||
{
|
{
|
||||||
if( memcmp( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ipLOCAL_MAC_ADDRESS, ipMAC_ADDRESS_LENGTH_BYTES ) == 0 )
|
NetworkEndPoint_t * pxEndPoint;
|
||||||
|
|
||||||
|
pxEndPoint = FreeRTOS_FindEndPointOnMAC( &( pxIPPacket->xEthernetHeader.xDestinationAddress ), NULL );
|
||||||
|
|
||||||
|
if(( memcmp( pxIPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ipLOCAL_MAC_ADDRESS, ipMAC_ADDRESS_LENGTH_BYTES ) == 0 )
|
||||||
|
&& ( pxEndPoint != NULL ) )
|
||||||
{
|
{
|
||||||
xResult = pdTRUE;
|
xResult = pdTRUE;
|
||||||
|
|
||||||
@@ -1233,6 +1320,9 @@ void FreeRTOS_ClearARP( void )
|
|||||||
{
|
{
|
||||||
IPStackEvent_t xRxEvent;
|
IPStackEvent_t xRxEvent;
|
||||||
|
|
||||||
|
pxUseDescriptor->pxInterface = pxEndPoint->pxNetworkInterface;
|
||||||
|
pxUseDescriptor->pxEndPoint = pxEndPoint;
|
||||||
|
|
||||||
xRxEvent.eEventType = eNetworkRxEvent;
|
xRxEvent.eEventType = eNetworkRxEvent;
|
||||||
xRxEvent.pvData = pxUseDescriptor;
|
xRxEvent.pvData = pxUseDescriptor;
|
||||||
|
|
||||||
|
|||||||
@@ -108,13 +108,15 @@ BaseType_t xCheckRequiresARPResolution( const NetworkBufferDescriptor_t * pxNetw
|
|||||||
* isn't a gateway defined) then return eCantSendPacket.
|
* isn't a gateway defined) then return eCantSendPacket.
|
||||||
*/
|
*/
|
||||||
eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress,
|
eARPLookupResult_t eARPGetCacheEntry( uint32_t * pulIPAddress,
|
||||||
MACAddress_t * const pxMACAddress );
|
MACAddress_t * const pxMACAddress,
|
||||||
|
struct xNetworkEndPoint ** ppxEndPoint );
|
||||||
|
|
||||||
#if ( ipconfigUSE_ARP_REVERSED_LOOKUP != 0 )
|
#if ( ipconfigUSE_ARP_REVERSED_LOOKUP != 0 )
|
||||||
|
|
||||||
/* Lookup an IP-address if only the MAC-address is known */
|
/* Lookup an IP-address if only the MAC-address is known */
|
||||||
eARPLookupResult_t eARPGetCacheEntryByMac( const MACAddress_t * const pxMACAddress,
|
eARPLookupResult_t eARPGetCacheEntryByMac( const MACAddress_t * const pxMACAddress,
|
||||||
uint32_t * pulIPAddress );
|
uint32_t * pulIPAddress,
|
||||||
|
struct xNetworkInterface ** ppxInterface );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -158,7 +160,7 @@ BaseType_t xCheckLoopback( NetworkBufferDescriptor_t * const pxDescriptor,
|
|||||||
void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress );
|
void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress );
|
||||||
|
|
||||||
/* Clear all entries in the ARp cache. */
|
/* Clear all entries in the ARp cache. */
|
||||||
/* TBD: void FreeRTOS_ClearARP( const struct xNetworkEndPoint * pxEndPoint ); */
|
void FreeRTOS_ClearARP( const struct xNetworkEndPoint * pxEndPoint );
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
Reference in New Issue
Block a user