summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus
diff options
context:
space:
mode:
authorAniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>2020-07-22 18:06:23 -0700
committerGitHub <noreply@github.com>2020-07-22 18:06:23 -0700
commite0d62163b08769fd74f020709c398f994088ca96 (patch)
treea4530c1c98f5a8eaf56d0d969a33339eb0f4a1d3 /FreeRTOS-Plus
parent8e36bee30eef2107e128edb58e83ee46e8241a91 (diff)
downloadfreertos-git-e0d62163b08769fd74f020709c398f994088ca96.tar.gz
Sync with +TCP amazon-FreeRTOS (#158)
* DNS.c commit * IP.c commit * Add various source & header files
Diffstat (limited to 'FreeRTOS-Plus')
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c584
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c691
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c11
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c6
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h25
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h6
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_dump_packets.h25
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_mem_stats.h25
8 files changed, 756 insertions, 617 deletions
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
index 18fe02932..fd2fe8507 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
@@ -112,6 +112,9 @@ type. */
#endif
#endif
+/* Define the ASCII value of '.' (Period/Full-stop). */
+#define ASCII_BASELINE_DOT 46U
+
/*
* Create a socket and bind it to the standard DNS port number. Return the
* the created socket - or NULL if the socket could not be created or bound.
@@ -217,8 +220,7 @@ static uint32_t prvGetHostByName( const char *pcHostName,
static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
- /* MISRA c 2012 rule 8.7: Below function may be used by
- external callees as well */
+ /* Utility function: Clear DNS cache by calling this function. */
void FreeRTOS_dnsclear( void )
{
( void ) memset( xDNSCache, 0x0, sizeof( xDNSCache ) );
@@ -327,9 +329,6 @@ typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
/*-----------------------------------------------------------*/
#if( ipconfigUSE_DNS_CACHE == 1 )
-
- /* MISRA c 2012 rule 8.7: Below function may be used by
- external callees as well */
uint32_t FreeRTOS_dnslookup( const char *pcHostName )
{
uint32_t ulIPAddress = 0UL;
@@ -501,8 +500,6 @@ typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
/*-----------------------------------------------------------*/
#if( ipconfigDNS_USE_CALLBACKS == 0 )
- /* MISRA c 2012 rule 8.7 ralxed since this function can
- be called from external sources as well */
uint32_t FreeRTOS_gethostbyname( const char *pcHostName )
{
return prvPrepareLookup( pcHostName );
@@ -532,8 +529,33 @@ TickType_t uxReadTimeOut_ticks = ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS;
as gethostbyname() may be called from different threads */
BaseType_t xHasRandom = pdFALSE;
TickType_t uxIdentifier = 0U;
+#if( ipconfigUSE_DNS_CACHE != 0 )
+ BaseType_t xLengthOk = pdFALSE;
+#endif
+
+ #if( ipconfigUSE_DNS_CACHE != 0 )
+ {
+ if( pcHostName != NULL )
+ {
+ size_t xLength = strlen( pcHostName ) + 1;
+ if( xLength <= ipconfigDNS_CACHE_NAME_LENGTH )
+ {
+ /* The name is not too long. */
+ xLengthOk = pdTRUE;
+ }
+ else
+ {
+ FreeRTOS_printf( ( "prvPrepareLookup: name is too long ( %lu > %lu )\n",
+ ( unsigned long ) xLength,
+ ( unsigned long ) ipconfigDNS_CACHE_NAME_LENGTH ) );
+ }
+ }
+ }
+ if( ( pcHostName != NULL ) && ( xLengthOk != pdFALSE ) )
+ #else
if( pcHostName != NULL )
+ #endif /* ( ipconfigUSE_DNS_CACHE != 0 ) */
{
/* If the supplied hostname is IP address, convert it to uint32_t
and return. */
@@ -647,7 +669,7 @@ TickType_t uxWriteTimeOut_ticks = ipconfigDNS_SEND_BLOCK_TIME_TICKS;
if( xDNSSocket != NULL )
{
/* Ideally we should check for the return value. But since we are passing
- correect parameters, and xDNSSocket is != NULL, the return value is
+ correct parameters, and xDNSSocket is != NULL, the return value is
going to be '0' i.e. success. Thus, return value is discarded */
( void ) FreeRTOS_setsockopt( xDNSSocket, 0, FREERTOS_SO_SNDTIMEO, &( uxWriteTimeOut_ticks ), sizeof( TickType_t ) );
( void ) FreeRTOS_setsockopt( xDNSSocket, 0, FREERTOS_SO_RCVTIMEO, &( uxReadTimeOut_ticks ), sizeof( TickType_t ) );
@@ -785,10 +807,12 @@ static const DNSMessage_t xDefaultPartDNSHeader =
0 /* No additional authorities. */
};
- /* Copy in the const part of the header. */
+ /* Copy in the const part of the header. Intentionally using different
+ * pointers with memcpy() to put the information in to correct place. */
( void ) memcpy( pucUDPPayloadBuffer, &( xDefaultPartDNSHeader ), sizeof( xDefaultPartDNSHeader ) );
- /* Write in a unique identifier. */
+ /* Write in a unique identifier. Cast the Payload Buffer to DNSMessage_t
+ * to easily access fields of the DNS Message. */
pxDNSMessageHeader = ipPOINTER_CAST( DNSMessage_t *, pucUDPPayloadBuffer );
pxDNSMessageHeader->usIdentifier = ( uint16_t ) uxIdentifier;
@@ -815,9 +839,7 @@ static const DNSMessage_t xDefaultPartDNSHeader =
{
pucByte++;
- /* MISRA c 2012 rule 10.4 relaxed for increased readability.
- Not writing 46U instead of '.' */
- while( ( *pucByte != ( uint8_t ) 0U ) && ( *pucByte != ( uint8_t ) '.' ) )
+ while( ( *pucByte != ( uint8_t ) 0U ) && ( *pucByte != ( uint8_t ) ASCII_BASELINE_DOT ) )
{
pucByte++;
}
@@ -830,7 +852,8 @@ static const DNSMessage_t xDefaultPartDNSHeader =
pucStart = pucByte;
} while( *pucByte != ( uint8_t ) 0U );
- /* Finish off the record. */
+ /* Finish off the record. Cast the record onto DNSTail_t stucture to easily
+ * access the fields of the DNS Message. */
pxTail = ipPOINTER_CAST(DNSTail_t *, &( pucByte[ 1 ] ) );
#if defined( _lint ) || defined( __COVERITY__ )
@@ -1012,9 +1035,6 @@ when ipconfigDNS_USE_CALLBACKS == 1
when ipconfigUSE_LLMNR == 1
for testing purposes, by the module iot_test_freertos_tcp.c
*/
-
-/* MISRA c 2012 rule 8.7: Function below may be used by external
-callees as well. */
uint32_t ulDNSHandlePacket( const NetworkBufferDescriptor_t *pxNetworkBuffer )
{
DNSMessage_t *pxDNSMessageHeader;
@@ -1076,6 +1096,8 @@ uint8_t *pucByte;
size_t uxSourceBytesRemaining;
uint16_t x, usDataLength, usQuestions;
uint16_t usType = 0U;
+BaseType_t xReturn = pdTRUE;
+
#if( ipconfigUSE_LLMNR == 1 )
uint16_t usClass = 0U;
#endif
@@ -1087,316 +1109,342 @@ uint16_t usType = 0U;
/* Ensure that the buffer is of at least minimal DNS message length. */
if( uxBufferLength < sizeof( DNSMessage_t ) )
{
- return dnsPARSE_ERROR;
+ xReturn = pdFALSE;
}
+ else
+ {
+ uxSourceBytesRemaining = uxBufferLength;
- uxSourceBytesRemaining = uxBufferLength;
+ /* Parse the DNS message header. Map the byte stream onto a structure
+ * for easier access. */
+ pxDNSMessageHeader = ipPOINTER_CAST( DNSMessage_t *, pucUDPPayloadBuffer );
- /* Parse the DNS message header.
- MISRA c 2012 rule 11.3 relaxed to make byte by byte traversal easier */
- pxDNSMessageHeader = ipPOINTER_CAST( DNSMessage_t *, pucUDPPayloadBuffer );
-
- /* Introduce a do {} while (0) to allow the use of breaks. */
- do
- {
- size_t uxBytesRead = 0U;
- size_t uxResult;
+ /* Introduce a do {} while (0) to allow the use of breaks. */
+ do
+ {
+ size_t uxBytesRead = 0U;
+ size_t uxResult;
- /* Start at the first byte after the header. */
- pucByte = &( pucUDPPayloadBuffer [ sizeof( DNSMessage_t ) ] );
- uxSourceBytesRemaining -= sizeof( DNSMessage_t );
+ /* Start at the first byte after the header. */
+ pucByte = &( pucUDPPayloadBuffer [ sizeof( DNSMessage_t ) ] );
+ uxSourceBytesRemaining -= sizeof( DNSMessage_t );
- /* Skip any question records. */
- usQuestions = FreeRTOS_ntohs( pxDNSMessageHeader->usQuestions );
+ /* Skip any question records. */
+ usQuestions = FreeRTOS_ntohs( pxDNSMessageHeader->usQuestions );
- for( x = 0U; x < usQuestions; x++ )
- {
- #if( ipconfigUSE_LLMNR == 1 )
+ for( x = 0U; x < usQuestions; x++ )
{
- if( x == 0U )
+ #if( ipconfigUSE_LLMNR == 1 )
{
- pcRequestedName = ( char * ) pucByte;
+ if( x == 0U )
+ {
+ pcRequestedName = ( char * ) pucByte;
+ }
}
- }
- #endif
+ #endif
#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
- if( x == 0U )
- {
- uxResult = prvReadNameField( pucByte,
- uxSourceBytesRemaining,
- pcName,
- sizeof( pcName ) );
-
- /* Check for a malformed response. */
- if( uxResult == 0U )
+ if( x == 0U )
{
- return dnsPARSE_ERROR;
+ uxResult = prvReadNameField( pucByte,
+ uxSourceBytesRemaining,
+ pcName,
+ sizeof( pcName ) );
+
+ /* Check for a malformed response. */
+ if( uxResult == 0U )
+ {
+ xReturn = pdFALSE;
+ break;
+ }
+ uxBytesRead += uxResult;
+ pucByte = &( pucByte[ uxResult ] );
+ uxSourceBytesRemaining -= uxResult;
}
- uxBytesRead += uxResult;
- pucByte = &( pucByte[ uxResult ] );
- uxSourceBytesRemaining -= uxResult;
- }
- else
+ else
#endif /* ipconfigUSE_DNS_CACHE || ipconfigDNS_USE_CALLBACKS */
- {
- /* Skip the variable length pcName field. */
- uxResult = prvSkipNameField( pucByte,
- uxSourceBytesRemaining );
-
- /* Check for a malformed response. */
- if( uxResult == 0U )
{
- return dnsPARSE_ERROR;
+ /* Skip the variable length pcName field. */
+ uxResult = prvSkipNameField( pucByte,
+ uxSourceBytesRemaining );
+
+ /* Check for a malformed response. */
+ if( uxResult == 0U )
+ {
+ xReturn = pdFALSE;
+ break;
+ }
+ uxBytesRead += uxResult;
+ pucByte = &( pucByte[ uxResult ] );
+ uxSourceBytesRemaining -= uxResult;
}
- uxBytesRead += uxResult;
- pucByte = &( pucByte[ uxResult ] );
- uxSourceBytesRemaining -= uxResult;
- }
- /* Check the remaining buffer size. */
- if( uxSourceBytesRemaining >= sizeof( uint32_t ) )
- {
- #if( ipconfigUSE_LLMNR == 1 )
+ /* Check the remaining buffer size. */
+ if( uxSourceBytesRemaining >= sizeof( uint32_t ) )
{
- /* usChar2u16 returns value in host endianness. */
- usType = usChar2u16( pucByte );
- usClass = usChar2u16( &( pucByte[ 2 ] ) );
- }
- #endif /* ipconfigUSE_LLMNR */
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ /* usChar2u16 returns value in host endianness. */
+ usType = usChar2u16( pucByte );
+ usClass = usChar2u16( &( pucByte[ 2 ] ) );
+ }
+ #endif /* ipconfigUSE_LLMNR */
- /* Skip the type and class fields. */
- pucByte = &( pucByte[ sizeof( uint32_t ) ] );
- uxSourceBytesRemaining -= sizeof( uint32_t );
+ /* Skip the type and class fields. */
+ pucByte = &( pucByte[ sizeof( uint32_t ) ] );
+ uxSourceBytesRemaining -= sizeof( uint32_t );
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ break;
+ }
}
- else
+
+ if( xReturn == pdFALSE )
{
- return dnsPARSE_ERROR;
+ /* No need to proceed. Break out of the do-while loop. */
+ break;
}
- }
- /* Search through the answer records. */
- pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers );
+ /* Search through the answer records. */
+ pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers );
- if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
- {
- const uint16_t usCount = ( uint16_t ) ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY;
-
- for( x = 0U; ( x < pxDNSMessageHeader->usAnswers ) && ( x < usCount ); x++ )
+ if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
{
- BaseType_t xDoAccept;
-
- uxResult = prvSkipNameField( pucByte,
- uxSourceBytesRemaining );
-
- /* Check for a malformed response. */
- if( uxResult == 0U )
+ const uint16_t usCount = ( uint16_t ) ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY;
+ uint16_t usNumARecordsStored = 0;
+
+ for( x = 0U; ( x < pxDNSMessageHeader->usAnswers ) && ( usNumARecordsStored < usCount ); x++ )
{
- return dnsPARSE_ERROR;
- }
+ BaseType_t xDoAccept;
+
+ uxResult = prvSkipNameField( pucByte,
+ uxSourceBytesRemaining );
+
+ /* Check for a malformed response. */
+ if( uxResult == 0U )
+ {
+ xReturn = pdFALSE;
+ break;
+ }
- uxBytesRead += uxResult;
- pucByte = &( pucByte[ uxResult ] );
- uxSourceBytesRemaining -= uxResult;
+ uxBytesRead += uxResult;
+ pucByte = &( pucByte[ uxResult ] );
+ uxSourceBytesRemaining -= uxResult;
- /* Is there enough data for an IPv4 A record answer and, if so,
- is this an A record? */
- if( uxSourceBytesRemaining < sizeof( uint16_t ) )
- {
- return dnsPARSE_ERROR;
- }
- usType = usChar2u16( pucByte );
+ /* Is there enough data for an IPv4 A record answer and, if so,
+ is this an A record? */
+ if( uxSourceBytesRemaining < sizeof( uint16_t ) )
+ {
+ xReturn = pdFALSE;
+ break;
+ }
+ usType = usChar2u16( pucByte );
- if( usType == ( uint16_t ) dnsTYPE_A_HOST )
- {
- if( uxSourceBytesRemaining >= ( sizeof( DNSAnswerRecord_t ) + ipSIZE_OF_IPv4_ADDRESS ) )
+ if( usType == ( uint16_t ) dnsTYPE_A_HOST )
{
- xDoAccept = pdTRUE;
+ if( uxSourceBytesRemaining >= ( sizeof( DNSAnswerRecord_t ) + ipSIZE_OF_IPv4_ADDRESS ) )
+ {
+ xDoAccept = pdTRUE;
+ }
+ else
+ {
+ xDoAccept = pdFALSE;
+ }
}
else
{
+ /* Unknown host type. */
xDoAccept = pdFALSE;
}
- }
- else
- {
- /* Unknown host type. */
- xDoAccept = pdFALSE;
- }
- if( xDoAccept != pdFALSE )
- {
- /* This is the required record type and is of sufficient size. */
- /* MISRA c 2012 rule 11.3 relaxed. pucByte is used for byte-by-byte
- traversal. */
- pxDNSAnswerRecord = ipPOINTER_CAST( DNSAnswerRecord_t *, pucByte );
- /* Sanity check the data length of an IPv4 answer. */
- if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == ( uint16_t ) sizeof( uint32_t ) )
+ if( xDoAccept != pdFALSE )
{
- /* Copy the IP address out of the record. */
- /* MISRA c 2012 rule 21.15 relaxed here since this seems
- to be the least cumbersome way to get the IP address
- from the record. */
- ( void ) memcpy( &( ulIPAddress ),
- &( pucByte[ sizeof( DNSAnswerRecord_t ) ] ),
- sizeof( uint32_t ) );
-
- #if( ipconfigDNS_USE_CALLBACKS == 1 )
+ /* This is the required record type and is of sufficient size. */
+ /* Mapping pucByte to a DNSAnswerRecord allows easy access of the
+ * fields of the structure. */
+ pxDNSAnswerRecord = ipPOINTER_CAST( DNSAnswerRecord_t *, pucByte );
+
+ /* Sanity check the data length of an IPv4 answer. */
+ if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == ( uint16_t ) sizeof( uint32_t ) )
{
- /* See if any asynchronous call was made to FreeRTOS_gethostbyname_a() */
- if( xDNSDoCallback( ( TickType_t ) pxDNSMessageHeader->usIdentifier, pcName, ulIPAddress ) != pdFALSE )
+ /* Copy the IP address out of the record. Using different pointers
+ * to copy only the portion we want is intentional here. */
+ ( void ) memcpy( &( ulIPAddress ),
+ &( pucByte[ sizeof( DNSAnswerRecord_t ) ] ),
+ sizeof( uint32_t ) );
+
+ #if( ipconfigDNS_USE_CALLBACKS == 1 )
{
- /* This device has requested this DNS look-up.
- The result may be stored in the DNS cache. */
- xDoStore = pdTRUE;
+ /* See if any asynchronous call was made to FreeRTOS_gethostbyname_a() */
+ if( xDNSDoCallback( ( TickType_t ) pxDNSMessageHeader->usIdentifier, pcName, ulIPAddress ) != pdFALSE )
+ {
+ /* This device has requested this DNS look-up.
+ The result may be stored in the DNS cache. */
+ xDoStore = pdTRUE;
+ }
}
- }
- #endif /* ipconfigDNS_USE_CALLBACKS == 1 */
- #if( ipconfigUSE_DNS_CACHE == 1 )
- {
- /* The reply will only be stored in the DNS cache when the
- request was issued by this device. */
- if( xDoStore != pdFALSE )
+ #endif /* ipconfigDNS_USE_CALLBACKS == 1 */
+ #if( ipconfigUSE_DNS_CACHE == 1 )
{
- ( void ) prvProcessDNSCache( pcName, &ulIPAddress, pxDNSAnswerRecord->ulTTL, pdFALSE );
+ char cBuffer[ 16 ];
+
+ /* The reply will only be stored in the DNS cache when the
+ request was issued by this device. */
+ if( xDoStore != pdFALSE )
+ {
+ ( void ) prvProcessDNSCache( pcName, &ulIPAddress, pxDNSAnswerRecord->ulTTL, pdFALSE );
+ usNumARecordsStored++; /* Track # of A records stored */
+ }
+
+ FreeRTOS_inet_ntop( FREERTOS_AF_INET, ( const void * ) &( ulIPAddress ), cBuffer, sizeof( cBuffer ) );
+ /* Show what has happened. */
+ FreeRTOS_printf( ( "DNS[0x%04lX]: The answer to '%s' (%s) will%s be stored\n",
+ ( UBaseType_t ) pxDNSMessageHeader->usIdentifier,
+ pcName,
+ cBuffer,
+ ( xDoStore != 0 ) ? "" : " NOT" ) );
}
-
- /* Show what has happened. */
- FreeRTOS_printf( ( "DNS[0x%04lX]: The answer to '%s' (%lxip) will%s be stored\n",
- ( UBaseType_t ) pxDNSMessageHeader->usIdentifier,
- pcName,
- ( UBaseType_t ) FreeRTOS_ntohl( ulIPAddress ),
- ( xDoStore != 0 ) ? "" : " NOT" ) );
+ #endif /* ipconfigUSE_DNS_CACHE */
}
- #endif /* ipconfigUSE_DNS_CACHE */
- }
-
- pucByte = &( pucByte[ sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) ] );
- uxSourceBytesRemaining -= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) );
- }
- else if( uxSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) )
- {
- /* It's not an A record, so skip it. Get the header location
- and then jump over the header. */
- /* MISRA c 2012 rule 11.3 relaxed as pucByte is being used in
- various places to point to various parts of the DNS records */
- pxDNSAnswerRecord = ipPOINTER_CAST( DNSAnswerRecord_t *, pucByte );
+ pucByte = &( pucByte[ sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) ] );
+ uxSourceBytesRemaining -= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) );
+ }
+ else if( uxSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) )
+ {
+ /* It's not an A record, so skip it. Get the header location
+ and then jump over the header. */
+ /* Cast the response to DNSAnswerRecord for easy access to fields of the DNS response. */
+ pxDNSAnswerRecord = ipPOINTER_CAST( DNSAnswerRecord_t *, pucByte );
- pucByte = &( pucByte[ sizeof( DNSAnswerRecord_t ) ] );
- uxSourceBytesRemaining -= sizeof( DNSAnswerRecord_t );
+ pucByte = &( pucByte[ sizeof( DNSAnswerRecord_t ) ] );
+ uxSourceBytesRemaining -= sizeof( DNSAnswerRecord_t );
- /* Determine the length of the answer data from the header. */
- usDataLength = FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength );
+ /* Determine the length of the answer data from the header. */
+ usDataLength = FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength );
- /* Jump over the answer. */
- if( uxSourceBytesRemaining >= usDataLength )
- {
- pucByte = &( pucByte[ usDataLength ] );
- uxSourceBytesRemaining -= usDataLength;
+ /* Jump over the answer. */
+ if( uxSourceBytesRemaining >= usDataLength )
+ {
+ pucByte = &( pucByte[ usDataLength ] );
+ uxSourceBytesRemaining -= usDataLength;
+ }
+ else
+ {
+ /* Malformed response. */
+ xReturn = pdFALSE;
+ break;
+ }
}
else
{
- /* Malformed response. */
- return dnsPARSE_ERROR;
+ /* Do nothing */
}
}
- else
- {
- /* Do nothing */
- }
}
- }
#if( ipconfigUSE_LLMNR == 1 )
- else if( ( usQuestions != ( uint16_t ) 0U ) && ( usType == dnsTYPE_A_HOST ) && ( usClass == dnsCLASS_IN ) && ( pcRequestedName != NULL ) )
- {
- /* If this is not a reply to our DNS request, it might an LLMNR
- request. */
- if( xApplicationDNSQueryHook( &( pcRequestedName[ 1 ] ) ) != pdFALSE )
+ else if( ( usQuestions != ( uint16_t ) 0U ) && ( usType == dnsTYPE_A_HOST ) && ( usClass == dnsCLASS_IN ) && ( pcRequestedName != NULL ) )
{
- int16_t usLength;
- NetworkBufferDescriptor_t *pxNewBuffer = NULL;
- NetworkBufferDescriptor_t *pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( pucUDPPayloadBuffer );
- LLMNRAnswer_t *pxAnswer;
- uint8_t *pucNewBuffer = NULL;
-
- if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
+ /* If this is not a reply to our DNS request, it might an LLMNR
+ request. */
+ if( xApplicationDNSQueryHook( &( pcRequestedName[ 1 ] ) ) != pdFALSE )
{
- size_t uxDataLength = uxBufferLength + sizeof( UDPHeader_t ) + sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
-
- /* Set the size of the outgoing packet. */
- pxNetworkBuffer->xDataLength = uxDataLength;
- pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, uxDataLength + sizeof( LLMNRAnswer_t ) );
-
- if( pxNewBuffer != NULL )
- {
- BaseType_t xOffset1, xOffset2;
-
- xOffset1 = ( BaseType_t ) ( pucByte - pucUDPPayloadBuffer );
- xOffset2 = ( BaseType_t ) ( ( ( uint8_t * ) pcRequestedName ) - pucUDPPayloadBuffer );
+ int16_t usLength;
+ NetworkBufferDescriptor_t *pxNewBuffer = NULL;
+ NetworkBufferDescriptor_t *pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( pucUDPPayloadBuffer );
+ LLMNRAnswer_t *pxAnswer;
+ uint8_t *pucNewBuffer = NULL;
- pxNetworkBuffer = pxNewBuffer;
- pucNewBuffer = &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
-
- pucByte = &( pucNewBuffer[ xOffset1 ] );
- pcRequestedName = ( char * ) &( pucNewBuffer[ xOffset2 ] );
- pxDNSMessageHeader = ipPOINTER_CAST( DNSMessage_t *, pucNewBuffer );
- }
- else
+ if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
{
- /* Just to indicate that the message may not be answered. */
- pxNetworkBuffer = NULL;
- }
- }
+ size_t uxDataLength = uxBufferLength + sizeof( UDPHeader_t ) + sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
- /* The test on 'pucNewBuffer' is only to satisfy lint. */
- if( ( pxNetworkBuffer != NULL ) && ( pucNewBuffer != NULL ) )
- {
- pxAnswer = ipPOINTER_CAST( LLMNRAnswer_t *, pucByte );
+ /* Set the size of the outgoing packet. */
+ pxNetworkBuffer->xDataLength = uxDataLength;
+ pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, uxDataLength + sizeof( LLMNRAnswer_t ) );
- /* We leave 'usIdentifier' and 'usQuestions' untouched */
- #ifndef _lint
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usFlags, dnsLLMNR_FLAGS_IS_REPONSE ); /* Set the response flag */
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usAnswers, 1 ); /* Provide a single answer */
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usAuthorityRRs, 0 ); /* No authority */
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usAdditionalRRs, 0 ); /* No additional info */
- #endif /* lint */
+ if( pxNewBuffer != NULL )
+ {
+ BaseType_t xOffset1, xOffset2;
- pxAnswer->ucNameCode = dnsNAME_IS_OFFSET;
- pxAnswer->ucNameOffset = ( uint8_t ) ( pcRequestedName - ( char * ) pucNewBuffer );
+ xOffset1 = ( BaseType_t ) ( pucByte - pucUDPPayloadBuffer );
+ xOffset2 = ( BaseType_t ) ( ( ( uint8_t * ) pcRequestedName ) - pucUDPPayloadBuffer );
- #ifndef _lint
- vSetField16( pxAnswer, LLMNRAnswer_t, usType, dnsTYPE_A_HOST ); /* Type A: host */
- vSetField16( pxAnswer, LLMNRAnswer_t, usClass, dnsCLASS_IN ); /* 1: Class IN */
- vSetField32( pxAnswer, LLMNRAnswer_t, ulTTL, dnsLLMNR_TTL_VALUE );
- vSetField16( pxAnswer, LLMNRAnswer_t, usDataLength, 4 );
- vSetField32( pxAnswer, LLMNRAnswer_t, ulIPAddress, FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) );
- #endif /* lint */
- usLength = ( int16_t ) ( sizeof( *pxAnswer ) + ( size_t ) ( pucByte - pucNewBuffer ) );
+ pxNetworkBuffer = pxNewBuffer;
+ pucNewBuffer = &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
- prvReplyDNSMessage( pxNetworkBuffer, usLength );
+ pucByte = &( pucNewBuffer[ xOffset1 ] );
+ pcRequestedName = ( char * ) &( pucNewBuffer[ xOffset2 ] );
+ pxDNSMessageHeader = ipPOINTER_CAST( DNSMessage_t *, pucNewBuffer );
+ }
+ else
+ {
+ /* Just to indicate that the message may not be answered. */
+ pxNetworkBuffer = NULL;
+ }
+ }
- if( pxNewBuffer != NULL )
+ /* The test on 'pucNewBuffer' is only to satisfy lint. */
+ if( ( pxNetworkBuffer != NULL ) && ( pucNewBuffer != NULL ) )
{
- vReleaseNetworkBufferAndDescriptor( pxNewBuffer );
+ pxAnswer = ipPOINTER_CAST( LLMNRAnswer_t *, pucByte );
+
+ /* We leave 'usIdentifier' and 'usQuestions' untouched */
+ #ifndef _lint
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usFlags, dnsLLMNR_FLAGS_IS_REPONSE ); /* Set the response flag */
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usAnswers, 1 ); /* Provide a single answer */
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usAuthorityRRs, 0 ); /* No authority */
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usAdditionalRRs, 0 ); /* No additional info */
+ #endif /* lint */
+
+ pxAnswer->ucNameCode = dnsNAME_IS_OFFSET;
+ pxAnswer->ucNameOffset = ( uint8_t ) ( pcRequestedName - ( char * ) pucNewBuffer );
+
+ #ifndef _lint
+ vSetField16( pxAnswer, LLMNRAnswer_t, usType, dnsTYPE_A_HOST ); /* Type A: host */
+ vSetField16( pxAnswer, LLMNRAnswer_t, usClass, dnsCLASS_IN ); /* 1: Class IN */
+ vSetField32( pxAnswer, LLMNRAnswer_t, ulTTL, dnsLLMNR_TTL_VALUE );
+ vSetField16( pxAnswer, LLMNRAnswer_t, usDataLength, 4 );
+ vSetField32( pxAnswer, LLMNRAnswer_t, ulIPAddress, FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) );
+ #endif /* lint */
+ usLength = ( int16_t ) ( sizeof( *pxAnswer ) + ( size_t ) ( pucByte - pucNewBuffer ) );
+
+ prvReplyDNSMessage( pxNetworkBuffer, usLength );
+
+ if( pxNewBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNewBuffer );
+ }
}
}
}
- }
- else
- {
- /* Not an expected reply. */
- }
+ else
+ {
+ /* Not an expected reply. */
+ }
#endif /* ipconfigUSE_LLMNR == 1 */
- ( void ) uxBytesRead;
- } while( ipFALSE_BOOL );
+ ( void ) uxBytesRead;
+ } while( ipFALSE_BOOL );
+ }
- if( xExpected == pdFALSE )
+ if( xReturn == pdFALSE )
+ {
+ /* There was an error while parsing the DNS response. Return error code. */
+ ulIPAddress = dnsPARSE_ERROR;
+ }
+ else if( xExpected == pdFALSE )
{
/* Do not return a valid IP-address in case the reply was not expected. */
ulIPAddress = 0UL;
}
+ else
+ {
+ /* The IP-address found will be returned. */
+ }
+
#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
( void ) xDoStore;
#endif
@@ -1567,22 +1615,25 @@ BaseType_t xReturn;
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
if( ( xSocket == FREERTOS_INVALID_SOCKET ) || ( xSocket == NULL ) )
{
- return NULL;
- }
-
- /* Auto bind the port. */
- xAddress.sin_port = 0U;
- xReturn = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
-
- /* Check the bind was successful, and clean up if not. */
- if( xReturn != 0 )
- {
- ( void ) FreeRTOS_closesocket( xSocket );
+ /* There was an error, return NULL. */
xSocket = NULL;
}
else
{
- /* The send and receive timeouts will be set later on. */
+ /* Auto bind the port. */
+ xAddress.sin_port = 0U;
+ xReturn = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
+
+ /* Check the bind was successful, and clean up if not. */
+ if( xReturn != 0 )
+ {
+ ( void ) FreeRTOS_closesocket( xSocket );
+ xSocket = NULL;
+ }
+ else
+ {
+ /* The send and receive timeouts will be set later on. */
+ }
}
return xSocket;
@@ -1651,9 +1702,6 @@ BaseType_t xReturn;
uint32_t ulIPAddressIndex = 0;
static BaseType_t xFreeEntry = 0;
- /* MISRA advisory rule 1.2 Relaxed in case of
- configASSERT as using __FUNCTION__ makes
- debugging easier */
configASSERT( ( pcName != NULL ) );
/* For each entry in the DNS cache table. */
@@ -1736,7 +1784,7 @@ BaseType_t xReturn;
xDNSCache[ xFreeEntry ].ucCurrentIPAddress = 0;
/* Initialize all remaining IP addresses in this entry to 0 */
- memset( &xDNSCache[ xFreeEntry ].ulIPAddresses[ 1 ],
+ ( void ) memset( &xDNSCache[ xFreeEntry ].ulIPAddresses[ 1 ],
0,
sizeof( xDNSCache[ xFreeEntry ].ulIPAddresses[ 1 ] ) *
( ( uint32_t ) ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY - 1U ) );
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
index 9fc53fa76..efb1348d1 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
@@ -798,7 +798,7 @@ const TickType_t xDontBlock = ( TickType_t ) 0;
iptraceNETWORK_DOWN();
}
/*-----------------------------------------------------------*/
-
+/* Utility function. Process Network Down event from ISR. */
BaseType_t FreeRTOS_NetworkDownFromISR( void )
{
static const IPStackEvent_t xNetworkDownEvent = { eNetworkDownEvent, NULL };
@@ -1288,6 +1288,7 @@ eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucE
eFrameProcessingResult_t eReturn;
const EthernetHeader_t *pxEthernetHeader;
+ /* Map the buffer onto Ethernet Header struct for easy access to fields. */
pxEthernetHeader = ipPOINTER_CAST( const EthernetHeader_t *, pucEthernetBuffer );
if( memcmp( ipLOCAL_MAC_ADDRESS, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
@@ -1427,6 +1428,8 @@ eFrameProcessingResult_t eReturned = eReleaseBuffer;
if( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) )
{
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
+
+ /* Map the buffer onto the Ethernet Header struct for easy access to the fields. */
pxEthernetHeader = ipPOINTER_CAST( const EthernetHeader_t *, pxNetworkBuffer->pucEthernetBuffer );
/* The condition "eReturned == eProcessBuffer" must be true. */
@@ -1688,156 +1691,166 @@ uint8_t ucProtocol;
if( ( uxHeaderLength > ( pxNetworkBuffer->xDataLength - ipSIZE_OF_ETH_HEADER ) ) ||
( uxHeaderLength < ipSIZE_OF_IPv4_HEADER ) )
{
- return eReleaseBuffer;
+ eReturn = eReleaseBuffer;
}
-
- ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
- /* Check if the IP headers are acceptable and if it has our destination. */
- eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );
-
- if( eReturn == eProcessBuffer )
+ else
{
- /* Are there IP-options. */
- if( uxHeaderLength > ipSIZE_OF_IPv4_HEADER )
+ ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
+ /* Check if the IP headers are acceptable and if it has our destination. */
+ eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );
+
+ if( eReturn == eProcessBuffer )
{
- /* The size of the IP-header is larger than 20 bytes.
- The extra space is used for IP-options. */
- #if( ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS != 0 )
- {
- /* All structs of headers expect a IP header size of 20 bytes
- * IP header options were included, we'll ignore them and cut them out. */
- const size_t optlen = ( ( size_t ) uxHeaderLength ) - ipSIZE_OF_IPv4_HEADER;
- /* From: the previous start of UDP/ICMP/TCP data. */
- const uint8_t *pucSource = ( const uint8_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ sizeof( EthernetHeader_t ) + uxHeaderLength ] );
- /* To: the usual start of UDP/ICMP/TCP data at offset 20 (decimal ) from IP header. */
- uint8_t *pucTarget = ( uint8_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ sizeof( EthernetHeader_t ) + ipSIZE_OF_IPv4_HEADER ] );
- /* How many: total length minus the options and the lower headers. */
- const size_t xMoveLen = pxNetworkBuffer->xDataLength - ( optlen + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_ETH_HEADER );
-
- ( void ) memmove( pucTarget, pucSource, xMoveLen );
- pxNetworkBuffer->xDataLength -= optlen;
-
- /* Rewrite the Version/IHL byte to indicate that this packet has no IP options. */
- pxIPHeader->ucVersionHeaderLength = ( pxIPHeader->ucVersionHeaderLength & 0xF0U ) | /* High nibble is the version. */
- ( ( ipSIZE_OF_IPv4_HEADER >> 2 ) & 0x0FU );
- }
- #else
+ /* Are there IP-options. */
+ if( uxHeaderLength > ipSIZE_OF_IPv4_HEADER )
{
- /* 'ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS' is not set, so packets carrying
- IP-options will be dropped. */
- return eReleaseBuffer;
+ /* The size of the IP-header is larger than 20 bytes.
+ The extra space is used for IP-options. */
+ #if( ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS != 0 )
+ {
+ /* All structs of headers expect a IP header size of 20 bytes
+ * IP header options were included, we'll ignore them and cut them out. */
+ const size_t optlen = ( ( size_t ) uxHeaderLength ) - ipSIZE_OF_IPv4_HEADER;
+ /* From: the previous start of UDP/ICMP/TCP data. */
+ const uint8_t *pucSource = ( const uint8_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ sizeof( EthernetHeader_t ) + uxHeaderLength ] );
+ /* To: the usual start of UDP/ICMP/TCP data at offset 20 (decimal ) from IP header. */
+ uint8_t *pucTarget = ( uint8_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ sizeof( EthernetHeader_t ) + ipSIZE_OF_IPv4_HEADER ] );
+ /* How many: total length minus the options and the lower headers. */
+ const size_t xMoveLen = pxNetworkBuffer->xDataLength - ( optlen + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_ETH_HEADER );
+
+ ( void ) memmove( pucTarget, pucSource, xMoveLen );
+ pxNetworkBuffer->xDataLength -= optlen;
+
+ /* Rewrite the Version/IHL byte to indicate that this packet has no IP options. */
+ pxIPHeader->ucVersionHeaderLength = ( pxIPHeader->ucVersionHeaderLength & 0xF0U ) | /* High nibble is the version. */
+ ( ( ipSIZE_OF_IPv4_HEADER >> 2 ) & 0x0FU );
+ }
+ #else
+ {
+ /* 'ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS' is not set, so packets carrying
+ IP-options will be dropped. */
+ eReturn = eReleaseBuffer;
+ }
+ #endif
}
- #endif
- }
- /* Add the IP and MAC addresses to the ARP table if they are not
- already there - otherwise refresh the age of the existing
- entry. */
- if( ucProtocol != ( uint8_t ) ipPROTOCOL_UDP )
- {
- /* Refresh the ARP cache with the IP/MAC-address of the received
- packet. For UDP packets, this will be done later in
- xProcessReceivedUDPPacket(), as soon as it's know that the message
- will be handled. This will prevent the ARP cache getting
- overwritten with the IP address of useless broadcast packets. */
- vARPRefreshCacheEntry( &( pxIPPacket->xEthernetHeader.xSourceAddress ), pxIPHeader->ulSourceIPAddress );
- }
- switch( ucProtocol )
- {
- case ipPROTOCOL_ICMP :
- /* The IP packet contained an ICMP frame. Don't bother checking
- the ICMP checksum, as if it is wrong then the wrong data will
- also be returned, and the source of the ping will know something
- went wrong because it will not be able to validate what it
- receives. */
- #if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+ if( eReturn != eReleaseBuffer )
+ {
+ /* Add the IP and MAC addresses to the ARP table if they are not
+ already there - otherwise refresh the age of the existing
+ entry. */
+ if( ucProtocol != ( uint8_t ) ipPROTOCOL_UDP )
{
- if( pxNetworkBuffer->xDataLength >= sizeof( ICMPPacket_t ) )
- {
- ICMPPacket_t *pxICMPPacket = ipPOINTER_CAST( ICMPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
- if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
- {
- eReturn = prvProcessICMPPacket( pxICMPPacket );
- }
- }
- else
- {
- eReturn = eReleaseBuffer;
- }
+ /* Refresh the ARP cache with the IP/MAC-address of the received
+ packet. For UDP packets, this will be done later in
+ xProcessReceivedUDPPacket(), as soon as it's know that the message
+ will be handled. This will prevent the ARP cache getting
+ overwritten with the IP address of useless broadcast packets. */
+ vARPRefreshCacheEntry( &( pxIPPacket->xEthernetHeader.xSourceAddress ), pxIPHeader->ulSourceIPAddress );
}
- #endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
- break;
-
- case ipPROTOCOL_UDP :
+ switch( ucProtocol )
{
- /* The IP packet contained a UDP frame. */
- const UDPPacket_t *pxUDPPacket = ipPOINTER_CAST( const UDPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
- uint16_t usLength;
-
- /* Note the header values required prior to the checksum
- generation as the checksum pseudo header may clobber some of
- these values. */
- usLength = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength );
- if ( ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) ) &&
- ( ( ( size_t ) usLength ) >= sizeof( UDPHeader_t ) ) )
- {
- size_t uxPayloadSize_1, uxPayloadSize_2;
- /* Ensure that downstream UDP packet handling has the lesser
- of: the actual network buffer Ethernet frame length, or
- the sender's UDP packet header payload length, minus the
- size of the UDP header.
-
- The size of the UDP packet structure in this implementation
- includes the size of the Ethernet header, the size of
- the IP header, and the size of the UDP header. */
- uxPayloadSize_1 = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
- uxPayloadSize_2 = ( ( size_t ) usLength ) - sizeof( UDPHeader_t );
- if( uxPayloadSize_1 > uxPayloadSize_2 )
+ case ipPROTOCOL_ICMP :
+ /* The IP packet contained an ICMP frame. Don't bother checking
+ the ICMP checksum, as if it is wrong then the wrong data will
+ also be returned, and the source of the ping will know something
+ went wrong because it will not be able to validate what it
+ receives. */
+ #if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
{
- pxNetworkBuffer->xDataLength = uxPayloadSize_2 + sizeof( UDPPacket_t );
+ if( pxNetworkBuffer->xDataLength >= sizeof( ICMPPacket_t ) )
+ {
+ /* Map the buffer onto a ICMP-Packet struct to easily access the
+ * fields of ICMP packet. */
+ ICMPPacket_t *pxICMPPacket = ipPOINTER_CAST( ICMPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
+ if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
+ {
+ eReturn = prvProcessICMPPacket( pxICMPPacket );
+ }
+ }
+ else
+ {
+ eReturn = eReleaseBuffer;
+ }
}
+ #endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
+ break;
- /* Fields in pxNetworkBuffer (usPort, ulIPAddress) are network order. */
- pxNetworkBuffer->usPort = pxUDPPacket->xUDPHeader.usSourcePort;
- pxNetworkBuffer->ulIPAddress = pxUDPPacket->xIPHeader.ulSourceIPAddress;
-
- /* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM:
- In some cases, the upper-layer checksum has been calculated
- by the NIC driver. */
-
- /* Pass the packet payload to the UDP sockets
- implementation. */
- if( xProcessReceivedUDPPacket( pxNetworkBuffer,
- pxUDPPacket->xUDPHeader.usDestinationPort ) == pdPASS )
+ case ipPROTOCOL_UDP :
{
- eReturn = eFrameConsumed;
+ /* The IP packet contained a UDP frame. */
+
+ /* Map the buffer onto a UDP-Packet struct to easily access the
+ * fields of UDP packet. */
+ const UDPPacket_t *pxUDPPacket = ipPOINTER_CAST( const UDPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
+ uint16_t usLength;
+
+ /* Note the header values required prior to the checksum
+ generation as the checksum pseudo header may clobber some of
+ these values. */
+ usLength = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength );
+ if ( ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) ) &&
+ ( ( ( size_t ) usLength ) >= sizeof( UDPHeader_t ) ) )
+ {
+ size_t uxPayloadSize_1, uxPayloadSize_2;
+ /* Ensure that downstream UDP packet handling has the lesser
+ of: the actual network buffer Ethernet frame length, or
+ the sender's UDP packet header payload length, minus the
+ size of the UDP header.
+
+ The size of the UDP packet structure in this implementation
+ includes the size of the Ethernet header, the size of
+ the IP header, and the size of the UDP header. */
+ uxPayloadSize_1 = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
+ uxPayloadSize_2 = ( ( size_t ) usLength ) - sizeof( UDPHeader_t );
+ if( uxPayloadSize_1 > uxPayloadSize_2 )
+ {
+ pxNetworkBuffer->xDataLength = uxPayloadSize_2 + sizeof( UDPPacket_t );
+ }
+
+ /* Fields in pxNetworkBuffer (usPort, ulIPAddress) are network order. */
+ pxNetworkBuffer->usPort = pxUDPPacket->xUDPHeader.usSourcePort;
+ pxNetworkBuffer->ulIPAddress = pxUDPPacket->xIPHeader.ulSourceIPAddress;
+
+ /* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM:
+ In some cases, the upper-layer checksum has been calculated
+ by the NIC driver. */
+
+ /* Pass the packet payload to the UDP sockets
+ implementation. */
+ if( xProcessReceivedUDPPacket( pxNetworkBuffer,
+ pxUDPPacket->xUDPHeader.usDestinationPort ) == pdPASS )
+ {
+ eReturn = eFrameConsumed;
+ }
+ }
+ else
+ {
+ eReturn = eReleaseBuffer;
+ }
}
- }
- else
- {
- eReturn = eReleaseBuffer;
- }
- }
- break;
+ break;
#if ipconfigUSE_TCP == 1
- case ipPROTOCOL_TCP :
- {
+ case ipPROTOCOL_TCP :
+ {
- if( xProcessReceivedTCPPacket( pxNetworkBuffer ) == pdPASS )
- {
- eReturn = eFrameConsumed;
- }
+ if( xProcessReceivedTCPPacket( pxNetworkBuffer ) == pdPASS )
+ {
+ eReturn = eFrameConsumed;
+ }
- /* Setting this variable will cause xTCPTimerCheck()
- to be called just before the IP-task blocks. */
- xProcessedTCPMessage++;
- }
- break;
+ /* Setting this variable will cause xTCPTimerCheck()
+ to be called just before the IP-task blocks. */
+ xProcessedTCPMessage++;
+ }
+ break;
#endif
- default :
- /* Not a supported frame type. */
- break;
+ default :
+ /* Not a supported frame type. */
+ break;
+ }
+ }
}
}
@@ -1995,7 +2008,8 @@ uint8_t ucProtocol;
break;
}
- /* Parse the packet length. */
+ /* Map the buffer onto a IP-Packet struct to easily access the
+ * fields of the IP packet. */
pxIPPacket = ipPOINTER_CAST( const IPPacket_t *, pucEthernetBuffer );
ucVersionHeaderLength = pxIPPacket->xIPHeader.ucVersionHeaderLength;
@@ -2028,11 +2042,13 @@ uint8_t ucProtocol;
/* Identify the next protocol. */
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
- /* N.B., if this IP packet header includes Options, then the following
+ /* If this IP packet header includes Options, then the following
assignment results in a pointer into the protocol packet with the Ethernet
and IP headers incorrectly aligned. However, either way, the "third"
protocol (Layer 3 or 4) header will be aligned, which is the convenience
of this calculation. */
+ /* Map the Buffer onto the Protocol Packet struct for easy access to the
+ * struct fields. */
pxProtPack = ipPOINTER_CAST( ProtocolPacket_t *, &( pucEthernetBuffer[ uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ] ) );
/* Switch on the Layer 3/4 protocol. */
@@ -2104,248 +2120,251 @@ uint16_t ucVersionHeaderLength;
BaseType_t location = 0;
- /* Check for minimum packet size. */
- if( uxBufferLength < sizeof( IPPacket_t ) )
+ /* Introduce a do-while loop to allow use of break statements.
+ * Note: MISRA prohibits use of 'goto', thus replaced with breaks. */
+ do
{
- usChecksum = ipINVALID_LENGTH;
- location = 1;
- goto error_exit;
- }
-
- /* Parse the packet length. */
- pxIPPacket = ipPOINTER_CAST( const IPPacket_t *, pucEthernetBuffer );
-
- /* Per https://tools.ietf.org/html/rfc791, the four-bit Internet Header
- Length field contains the length of the internet header in 32-bit words. */
- ucVersionHeaderLength = pxIPPacket->xIPHeader.ucVersionHeaderLength;
- ucVersionHeaderLength = ( ucVersionHeaderLength & ( uint8_t ) 0x0FU ) << 2;
- uxIPHeaderLength = ( UBaseType_t ) ucVersionHeaderLength;
-
- /* Check for minimum packet size. */
- if( uxBufferLength < ( sizeof( IPPacket_t ) + ( uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ) ) )
- {
- usChecksum = ipINVALID_LENGTH;
- location = 2;
- goto error_exit;
- }
- usLength = pxIPPacket->xIPHeader.usLength;
- usLength = FreeRTOS_ntohs( usLength );
- if( uxBufferLength < ( size_t ) ( ipSIZE_OF_ETH_HEADER + ( size_t ) usLength ) )
- {
- usChecksum = ipINVALID_LENGTH;
- location = 3;
- goto error_exit;
- }
-
- /* Identify the next protocol. */
- ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
-
- /* N.B., if this IP packet header includes Options, then the following
- assignment results in a pointer into the protocol packet with the Ethernet
- and IP headers incorrectly aligned. However, either way, the "third"
- protocol (Layer 3 or 4) header will be aligned, which is the convenience
- of this calculation. */
- pxProtPack = ipPOINTER_CAST( ProtocolPacket_t *, &( pucEthernetBuffer[ uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ] ) );
-
- /* Switch on the Layer 3/4 protocol. */
- if( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP )
- {
- if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_UDP_HEADER ) )
+ /* Check for minimum packet size. */
+ if( uxBufferLength < sizeof( IPPacket_t ) )
{
usChecksum = ipINVALID_LENGTH;
- location = 4;
- goto error_exit;
+ location = 1;
+ break;
}
- pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) );
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ /* Parse the packet length. */
+ pxIPPacket = ipPOINTER_CAST( const IPPacket_t *, pucEthernetBuffer );
+
+ /* Per https://tools.ietf.org/html/rfc791, the four-bit Internet Header
+ Length field contains the length of the internet header in 32-bit words. */
+ ucVersionHeaderLength = pxIPPacket->xIPHeader.ucVersionHeaderLength;
+ ucVersionHeaderLength = ( ucVersionHeaderLength & ( uint8_t ) 0x0FU ) << 2;
+ uxIPHeaderLength = ( UBaseType_t ) ucVersionHeaderLength;
+
+ /* Check for minimum packet size. */
+ if( uxBufferLength < ( sizeof( IPPacket_t ) + ( uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ) ) )
{
- pcType = "UDP";
+ usChecksum = ipINVALID_LENGTH;
+ location = 2;
+ break;
}
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- }
- else if( ucProtocol == ( uint8_t ) ipPROTOCOL_TCP )
- {
- if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_TCP_HEADER ) )
+ usLength = pxIPPacket->xIPHeader.usLength;
+ usLength = FreeRTOS_ntohs( usLength );
+ if( uxBufferLength < ( size_t ) ( ipSIZE_OF_ETH_HEADER + ( size_t ) usLength ) )
{
usChecksum = ipINVALID_LENGTH;
- location = 5;
- goto error_exit;
+ location = 3;
+ break;
}
- pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ /* Identify the next protocol. */
+ ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
+
+ /* N.B., if this IP packet header includes Options, then the following
+ assignment results in a pointer into the protocol packet with the Ethernet
+ and IP headers incorrectly aligned. However, either way, the "third"
+ protocol (Layer 3 or 4) header will be aligned, which is the convenience
+ of this calculation. */
+ pxProtPack = ipPOINTER_CAST( ProtocolPacket_t *, &( pucEthernetBuffer[ uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ] ) );
+
+ /* Switch on the Layer 3/4 protocol. */
+ if( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP )
{
- pcType = "TCP";
+ if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_UDP_HEADER ) )
+ {
+ usChecksum = ipINVALID_LENGTH;
+ location = 4;
+ break;
+ }
+
+ pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) );
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ pcType = "UDP";
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
}
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- }
- else if( ( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) ||
- ( ucProtocol == ( uint8_t ) ipPROTOCOL_IGMP ) )
- {
- if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_ICMP_HEADER ) )
+ else if( ucProtocol == ( uint8_t ) ipPROTOCOL_TCP )
{
- usChecksum = ipINVALID_LENGTH;
- location = 6;
- goto error_exit;
- }
+ if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_TCP_HEADER ) )
+ {
+ usChecksum = ipINVALID_LENGTH;
+ location = 5;
+ break;
+ }
- pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ pcType = "TCP";
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ }
+ else if( ( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) ||
+ ( ucProtocol == ( uint8_t ) ipPROTOCOL_IGMP ) )
{
- if( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
+ if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_ICMP_HEADER ) )
{
- pcType = "ICMP";
+ usChecksum = ipINVALID_LENGTH;
+ location = 6;
+ break;
}
- else
+
+ pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
{
- pcType = "IGMP";
+ if( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
+ {
+ pcType = "ICMP";
+ }
+ else
+ {
+ pcType = "IGMP";
+ }
}
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ }
+ else
+ {
+ /* Unhandled protocol, other than ICMP, IGMP, UDP, or TCP. */
+ usChecksum = ipUNHANDLED_PROTOCOL;
+ location = 7;
+ break;
}
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- }
- else
- {
- /* Unhandled protocol, other than ICMP, IGMP, UDP, or TCP. */
- usChecksum = ipUNHANDLED_PROTOCOL;
- location = 7;
- goto error_exit;
- }
- /* The protocol and checksum field have been identified. Check the direction
- of the packet. */
- if( xOutgoingPacket != pdFALSE )
- {
- /* This is an outgoing packet. Before calculating the checksum, set it
- to zero. */
- *( pusChecksum ) = 0U;
- }
- else if( ( *pusChecksum == 0U ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
- {
- #if( ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS == 0 )
+ /* The protocol and checksum field have been identified. Check the direction
+ of the packet. */
+ if( xOutgoingPacket != pdFALSE )
{
- /* Sender hasn't set the checksum, drop the packet because
- ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS is not set. */
- usChecksum = ipWRONG_CRC;
- #if( ipconfigHAS_PRINTF != 0 )
+ /* This is an outgoing packet. Before calculating the checksum, set it
+ to zero. */
+ *( pusChecksum ) = 0U;
+ }
+ else if( ( *pusChecksum == 0U ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
+ {
+ #if( ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS == 0 )
{
- static BaseType_t xCount = 0;
-
- if( xCount < 5 )
+ /* Sender hasn't set the checksum, drop the packet because
+ ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS is not set. */
+ usChecksum = ipWRONG_CRC;
+ #if( ipconfigHAS_PRINTF != 0 )
{
- FreeRTOS_printf( ( "usGenerateProtocolChecksum: UDP packet from %xip without CRC dropped\n",
- FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ) ) );
- xCount++;
+ static BaseType_t xCount = 0;
+
+ if( xCount < 5 )
+ {
+ FreeRTOS_printf( ( "usGenerateProtocolChecksum: UDP packet from %xip without CRC dropped\n",
+ FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ) ) );
+ xCount++;
+ }
}
+ #endif /* ( ipconfigHAS_PRINTF != 0 ) */
+ }
+ #else
+ {
+ /* Sender hasn't set the checksum, no use to calculate it. */
+ usChecksum = ipCORRECT_CRC;
}
- #endif /* ( ipconfigHAS_PRINTF != 0 ) */
+ #endif
+ location = 8;
+ break;
}
- #else
+ else
{
- /* Sender hasn't set the checksum, no use to calculate it. */
- usChecksum = ipCORRECT_CRC;
+ /* Other incoming packet than UDP. */
}
- #endif
- location = 8;
- goto error_exit;
- }
- else
- {
- /* Other incoming packet than UDP. */
- }
- usLength = pxIPPacket->xIPHeader.usLength;
- usLength = FreeRTOS_ntohs( usLength );
- ulLength = ( uint32_t ) usLength;
- ulLength -= ( ( uint16_t ) uxIPHeaderLength ); /* normally minus 20 */
+ usLength = pxIPPacket->xIPHeader.usLength;
+ usLength = FreeRTOS_ntohs( usLength );
+ ulLength = ( uint32_t ) usLength;
+ ulLength -= ( ( uint16_t ) uxIPHeaderLength ); /* normally minus 20 */
- if( ( ulLength < ( ( uint32_t ) sizeof( pxProtPack->xUDPPacket.xUDPHeader ) ) ) ||
- ( ulLength > ( ( uint32_t ) ipconfigNETWORK_MTU - ( uint32_t ) uxIPHeaderLength ) ) )
- {
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ if( ( ulLength < ( ( uint32_t ) sizeof( pxProtPack->xUDPPacket.xUDPHeader ) ) ) ||
+ ( ulLength > ( ( uint32_t ) ipconfigNETWORK_MTU - ( uint32_t ) uxIPHeaderLength ) ) )
{
- FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: len invalid: %lu\n", pcType, ulLength ) );
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: len invalid: %lu\n", pcType, ulLength ) );
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- /* Again, in a 16-bit return value there is no space to indicate an
- error. For incoming packets, 0x1234 will cause dropping of the packet.
- For outgoing packets, there is a serious problem with the
- format/length */
- usChecksum = ipINVALID_LENGTH;
- location = 9;
- goto error_exit;
- }
- if( ucProtocol <= ( uint8_t ) ipPROTOCOL_IGMP )
- {
- /* ICMP/IGMP do not have a pseudo header for CRC-calculation. */
- usChecksum = ( uint16_t )
- ( ~usGenerateChecksum( 0U,
- ( uint8_t * ) &( pxProtPack->xTCPPacket.xTCPHeader ), ( size_t ) ulLength ) );
- }
- else
- {
- /* For UDP and TCP, sum the pseudo header, i.e. IP protocol + length
- fields */
- usChecksum = ( uint16_t ) ( ulLength + ( ( uint16_t ) ucProtocol ) );
+ /* Again, in a 16-bit return value there is no space to indicate an
+ error. For incoming packets, 0x1234 will cause dropping of the packet.
+ For outgoing packets, there is a serious problem with the
+ format/length */
+ usChecksum = ipINVALID_LENGTH;
+ location = 9;
+ break;
+ }
+ if( ucProtocol <= ( uint8_t ) ipPROTOCOL_IGMP )
+ {
+ /* ICMP/IGMP do not have a pseudo header for CRC-calculation. */
+ usChecksum = ( uint16_t )
+ ( ~usGenerateChecksum( 0U,
+ ( uint8_t * ) &( pxProtPack->xTCPPacket.xTCPHeader ), ( size_t ) ulLength ) );
+ }
+ else
+ {
+ /* For UDP and TCP, sum the pseudo header, i.e. IP protocol + length
+ fields */
+ usChecksum = ( uint16_t ) ( ulLength + ( ( uint16_t ) ucProtocol ) );
- /* And then continue at the IPv4 source and destination addresses. */
- usChecksum = ( uint16_t )
- ( ~usGenerateChecksum( usChecksum,
- ipPOINTER_CAST( const uint8_t *, &( pxIPPacket->xIPHeader.ulSourceIPAddress ) ),
- ( size_t )( ( 2U * ipSIZE_OF_IPv4_ADDRESS ) + ulLength ) ) );
- /* Sum TCP header and data. */
- }
+ /* And then continue at the IPv4 source and destination addresses. */
+ usChecksum = ( uint16_t )
+ ( ~usGenerateChecksum( usChecksum,
+ ipPOINTER_CAST( const uint8_t *, &( pxIPPacket->xIPHeader.ulSourceIPAddress ) ),
+ ( size_t )( ( 2U * ipSIZE_OF_IPv4_ADDRESS ) + ulLength ) ) );
+ /* Sum TCP header and data. */
+ }
- if( xOutgoingPacket == pdFALSE )
- {
- /* This is in incoming packet. If the CRC is correct, it should be zero. */
- if( usChecksum == 0U )
+ if( xOutgoingPacket == pdFALSE )
{
- usChecksum = ( uint16_t )ipCORRECT_CRC;
+ /* This is in incoming packet. If the CRC is correct, it should be zero. */
+ if( usChecksum == 0U )
+ {
+ usChecksum = ( uint16_t )ipCORRECT_CRC;
+ }
}
- }
- else
- {
- if( ( usChecksum == 0U ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
+ else
{
- /* In case of UDP, a calculated checksum of 0x0000 is transmitted
- as 0xffff. A value of zero would mean that the checksum is not used. */
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ if( ( usChecksum == 0U ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
{
- if( xOutgoingPacket != pdFALSE )
+ /* In case of UDP, a calculated checksum of 0x0000 is transmitted
+ as 0xffff. A value of zero would mean that the checksum is not used. */
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
{
- FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: crc swap: %04X\n", pcType, usChecksum ) );
+ if( xOutgoingPacket != pdFALSE )
+ {
+ FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: crc swap: %04X\n", pcType, usChecksum ) );
+ }
}
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- usChecksum = ( uint16_t )0xffffu;
+ usChecksum = ( uint16_t )0xffffu;
+ }
}
- }
- usChecksum = FreeRTOS_htons( usChecksum );
+ usChecksum = FreeRTOS_htons( usChecksum );
- if( xOutgoingPacket != pdFALSE )
- {
- *( pusChecksum ) = usChecksum;
- }
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- else if( ( xOutgoingPacket == pdFALSE ) && ( usChecksum != ipCORRECT_CRC ) )
- {
- FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: ID %04X: from %lxip to %lxip bad crc: %04X\n",
- pcType,
- FreeRTOS_ntohs( pxIPPacket->xIPHeader.usIdentification ),
- FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ),
- FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulDestinationIPAddress ),
- FreeRTOS_ntohs( *pusChecksum ) ) );
- }
- else
- {
- /* Nothing. */
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
-
- error_exit:
+ if( xOutgoingPacket != pdFALSE )
+ {
+ *( pusChecksum ) = usChecksum;
+ }
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ else if( ( xOutgoingPacket == pdFALSE ) && ( usChecksum != ipCORRECT_CRC ) )
+ {
+ FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: ID %04X: from %lxip to %lxip bad crc: %04X\n",
+ pcType,
+ FreeRTOS_ntohs( pxIPPacket->xIPHeader.usIdentification ),
+ FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ),
+ FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulDestinationIPAddress ),
+ FreeRTOS_ntohs( *pusChecksum ) ) );
+ }
+ else
+ {
+ /* Nothing. */
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ } while( ipFALSE_BOOL );
if( ( usChecksum == ipUNHANDLED_PROTOCOL ) ||
( usChecksum == ipINVALID_LENGTH ) )
@@ -2482,7 +2501,9 @@ size_t uxDataLengthBytes = uxByteCount;
xLastSource.u8ptr = ( uint8_t * ) ( xSource.u8ptr + ( uxDataLengthBytes & ~( ( size_t ) 1 ) ) );
/* Half-word aligned. */
- /* The operator "<" is being applied to the pointers "xSource.u16ptr" and "xLastSource.u16ptr", which do not point into the same object. */
+ /* Coverity does not like Unions. Warning issued here: "The operator "<"
+ * is being applied to the pointers "xSource.u16ptr" and "xLastSource.u16ptr",
+ * which do not point into the same object." */
while( xSource.u16ptr < xLastSource.u16ptr )
{
/* At least one more short. */
@@ -2516,6 +2537,8 @@ size_t uxDataLengthBytes = uxByteCount;
}
/*-----------------------------------------------------------*/
+/* This function is used in other files, has external linkage e.g. in
+ * FreeRTOS_DNS.c. Not to be made static. */
void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend )
{
EthernetHeader_t *pxEthernetHeader;
@@ -2554,6 +2577,7 @@ EthernetHeader_t *pxEthernetHeader;
if( pxNetworkBuffer != NULL )
#endif
{
+ /* Map the Buffer to Ethernet Header struct for easy access to fields. */
pxEthernetHeader = ipPOINTER_CAST( EthernetHeader_t *, pxNetworkBuffer->pucEthernetBuffer );
/* Swap source and destination MAC addresses. */
@@ -2769,7 +2793,8 @@ BaseType_t FreeRTOS_IsNetworkUp( void )
}
#endif
/*-----------------------------------------------------------*/
-
+/* Utility function: Convert error number to a human readable
+ * string. Decalartion in FreeRTOS_errno_TCP.h. */
const char *FreeRTOS_strerror_r( BaseType_t xErrnum, char *pcBuffer, size_t uxLength )
{
const char *pcName;
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
index d960088e0..b2aa187e8 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
@@ -874,6 +874,9 @@ NetworkBufferDescriptor_t xTempBuffer;
usPacketIdentifier++;
pxIPHeader->usFragmentOffset = 0U;
+ /* Important: tell NIC driver how many bytes must be sent. */
+ pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
+
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
{
/* calculate the IP header checksum, in case the driver won't do that. */
@@ -899,9 +902,6 @@ NetworkBufferDescriptor_t xTempBuffer;
}
#endif
- /* Important: tell NIC driver how many bytes must be sent. */
- pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
-
/* Fill in the destination MAC addresses. */
( void ) memcpy( &( pxEthernetHeader->xDestinationAddress ),
&( pxEthernetHeader->xSourceAddress ),
@@ -2000,6 +2000,7 @@ int32_t lCount, lLength;
/* A txStream has been created already, see if the socket has new data for
the sliding window.
+
uxStreamBufferMidSpace() returns the distance between rxHead and rxMid. It
contains new Tx data which has not been passed to the sliding window yet.
The oldest data not-yet-confirmed can be found at rxTail. */
@@ -2009,6 +2010,7 @@ int32_t lCount, lLength;
{
/* All data between txMid and rxHead will now be passed to the sliding
window manager, so it can start transmitting them.
+
Hand over the new data to the sliding window handler. It will be
split-up in chunks of 1460 bytes each (or less, depending on
ipconfigTCP_MSS). */
@@ -2141,6 +2143,7 @@ uint16_t usLength;
/* Determine the length and the offset of the user-data sent to this
node.
+
The size of the TCP header is given in a multiple of 4-byte words (single
byte, needs no ntoh() translation). A shift-right 2: is the same as
(offset >> 4) * 4. */
@@ -2216,6 +2219,7 @@ BaseType_t xResult = 0;
{
/* See if way may accept the data contents and forward it to the socket
owner.
+
If it can't be "accept"ed it may have to be stored and send a selective
ack (SACK) option to confirm it. In that case, lTCPAddRxdata() will be
called later to store an out-of-order packet (in case lOffset is
@@ -3504,3 +3508,4 @@ const ListItem_t *pxEndTCP = ipPOINTER_CAST( const ListItem_t *, listGET_END_MAR
#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
#include "aws_freertos_tcp_verification_access_tcp_define.h"
#endif
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
index f827175ec..de1dd5ca3 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
@@ -1910,8 +1910,8 @@ const int32_t l500ms = 500;
#if( ipconfigUSE_TCP_WIN == 0 )
- static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize );
- static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize )
+ static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t const * pxWindow, uint32_t ulWindowSize );
+ static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t const * pxWindow, uint32_t ulWindowSize )
{
BaseType_t xReturn;
@@ -1934,7 +1934,7 @@ const int32_t l500ms = 500;
BaseType_t xTCPWindowTxHasData( TCPWindow_t const *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay )
{
- TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
+ TCPSegment_t const *pxSegment = &( pxWindow->xTxSegment );
BaseType_t xReturn;
TickType_t ulAge, ulMaxAge;
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
index c0ae4ed10..cef40d899 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
@@ -317,20 +317,25 @@ from the FreeRTOSIPConfig.h configuration header file. */
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
#endif
-
-#ifndef ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS
- #define ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS 1
-#endif
-
-#ifndef ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS
- #define ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS 0
-#endif
-
-
+/* Configuration to control whether packets with IP options,
+ * received over the network, should be passed up to the
+ * software stack OR should be dropped.
+ * If set to 1, the stack accepts IP packets that contain IP options, but does
+ * not process the options (IP options are not supported).
+ * If set to 0, the stack will drop IP packets that contain IP options.
+ */
#ifndef ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS
#define ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS 1
#endif
+/* Configuration to control whether UDP packets with
+ * checksum value of zero should be passed up the software
+ * stack OR should be dropped.
+ * If set to 1, the stack will accept UDP packets that have their checksum
+ * value set to 0.
+ * If set to 0, the stack will drop UDP packets that have their checksum value
+ * set to 0.
+ */
#ifndef ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS
#define ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS 0
#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
index fc0dc4683..5aeecaf93 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
@@ -304,6 +304,12 @@ BaseType_t FreeRTOS_IsNetworkUp( void );
UBaseType_t uxGetMinimumIPQueueSpace( void );
#endif
+#if ( ipconfigHAS_PRINTF != 0 )
+ extern void vPrintResourceStats( void );
+#else
+ #define vPrintResourceStats() do {} while( ipFALSE_BOOL )
+#endif
+
/*
* Defined in FreeRTOS_Sockets.c
* //_RB_ Don't think this comment is correct. If this is for internal use only it should appear after all the public API functions and not start with FreeRTOS_.
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_dump_packets.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_dump_packets.h
index 0b0cfed0f..7dd369023 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_dump_packets.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_dump_packets.h
@@ -1,4 +1,29 @@
/*
+ * FreeRTOS+TCP V2.2.1
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/*
* dump_packets.c
* Used in the PC/Win project to dump Ethernet packets, along with some description.
*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_mem_stats.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_mem_stats.h
index f20cef4d9..d07956f4a 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_mem_stats.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/tcp_mem_stats.h
@@ -1,4 +1,29 @@
/*
+ * FreeRTOS+TCP V2.2.1
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/*
* tcp_mem_stats.h
*/