Sync with +TCP amazon-FreeRTOS (#158)

* DNS.c commit

* IP.c commit

* Add various source & header files
This commit is contained in:
Aniruddha Kanhere
2020-07-22 18:06:23 -07:00
committed by GitHub
parent 8e36bee30e
commit e0d62163b0
8 changed files with 826 additions and 687 deletions

View File

@ -112,6 +112,9 @@ type. */
#endif #endif
#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 * 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. * 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 ]; static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
/* MISRA c 2012 rule 8.7: Below function may be used by /* Utility function: Clear DNS cache by calling this function. */
external callees as well */
void FreeRTOS_dnsclear( void ) void FreeRTOS_dnsclear( void )
{ {
( void ) memset( xDNSCache, 0x0, sizeof( xDNSCache ) ); ( void ) memset( xDNSCache, 0x0, sizeof( xDNSCache ) );
@ -327,9 +329,6 @@ typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( ipconfigUSE_DNS_CACHE == 1 ) #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 FreeRTOS_dnslookup( const char *pcHostName )
{ {
uint32_t ulIPAddress = 0UL; uint32_t ulIPAddress = 0UL;
@ -501,8 +500,6 @@ typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( ipconfigDNS_USE_CALLBACKS == 0 ) #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 ) uint32_t FreeRTOS_gethostbyname( const char *pcHostName )
{ {
return prvPrepareLookup( 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 */ as gethostbyname() may be called from different threads */
BaseType_t xHasRandom = pdFALSE; BaseType_t xHasRandom = pdFALSE;
TickType_t uxIdentifier = 0U; TickType_t uxIdentifier = 0U;
#if( ipconfigUSE_DNS_CACHE != 0 )
BaseType_t xLengthOk = pdFALSE;
#endif
#if( ipconfigUSE_DNS_CACHE != 0 )
{
if( pcHostName != NULL ) 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 /* If the supplied hostname is IP address, convert it to uint32_t
and return. */ and return. */
@ -647,7 +669,7 @@ TickType_t uxWriteTimeOut_ticks = ipconfigDNS_SEND_BLOCK_TIME_TICKS;
if( xDNSSocket != NULL ) if( xDNSSocket != NULL )
{ {
/* Ideally we should check for the return value. But since we are passing /* 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 */ 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_SNDTIMEO, &( uxWriteTimeOut_ticks ), sizeof( TickType_t ) );
( void ) FreeRTOS_setsockopt( xDNSSocket, 0, FREERTOS_SO_RCVTIMEO, &( uxReadTimeOut_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. */ 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 ) ); ( 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 = ipPOINTER_CAST( DNSMessage_t *, pucUDPPayloadBuffer );
pxDNSMessageHeader->usIdentifier = ( uint16_t ) uxIdentifier; pxDNSMessageHeader->usIdentifier = ( uint16_t ) uxIdentifier;
@ -815,9 +839,7 @@ static const DNSMessage_t xDefaultPartDNSHeader =
{ {
pucByte++; pucByte++;
/* MISRA c 2012 rule 10.4 relaxed for increased readability. while( ( *pucByte != ( uint8_t ) 0U ) && ( *pucByte != ( uint8_t ) ASCII_BASELINE_DOT ) )
Not writing 46U instead of '.' */
while( ( *pucByte != ( uint8_t ) 0U ) && ( *pucByte != ( uint8_t ) '.' ) )
{ {
pucByte++; pucByte++;
} }
@ -830,7 +852,8 @@ static const DNSMessage_t xDefaultPartDNSHeader =
pucStart = pucByte; pucStart = pucByte;
} while( *pucByte != ( uint8_t ) 0U ); } 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 ] ) ); pxTail = ipPOINTER_CAST(DNSTail_t *, &( pucByte[ 1 ] ) );
#if defined( _lint ) || defined( __COVERITY__ ) #if defined( _lint ) || defined( __COVERITY__ )
@ -1012,9 +1035,6 @@ when ipconfigDNS_USE_CALLBACKS == 1
when ipconfigUSE_LLMNR == 1 when ipconfigUSE_LLMNR == 1
for testing purposes, by the module iot_test_freertos_tcp.c 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 ) uint32_t ulDNSHandlePacket( const NetworkBufferDescriptor_t *pxNetworkBuffer )
{ {
DNSMessage_t *pxDNSMessageHeader; DNSMessage_t *pxDNSMessageHeader;
@ -1076,6 +1096,8 @@ uint8_t *pucByte;
size_t uxSourceBytesRemaining; size_t uxSourceBytesRemaining;
uint16_t x, usDataLength, usQuestions; uint16_t x, usDataLength, usQuestions;
uint16_t usType = 0U; uint16_t usType = 0U;
BaseType_t xReturn = pdTRUE;
#if( ipconfigUSE_LLMNR == 1 ) #if( ipconfigUSE_LLMNR == 1 )
uint16_t usClass = 0U; uint16_t usClass = 0U;
#endif #endif
@ -1087,13 +1109,14 @@ uint16_t usType = 0U;
/* Ensure that the buffer is of at least minimal DNS message length. */ /* Ensure that the buffer is of at least minimal DNS message length. */
if( uxBufferLength < sizeof( DNSMessage_t ) ) if( uxBufferLength < sizeof( DNSMessage_t ) )
{ {
return dnsPARSE_ERROR; xReturn = pdFALSE;
} }
else
{
uxSourceBytesRemaining = uxBufferLength; uxSourceBytesRemaining = uxBufferLength;
/* Parse the DNS message header. /* Parse the DNS message header. Map the byte stream onto a structure
MISRA c 2012 rule 11.3 relaxed to make byte by byte traversal easier */ * for easier access. */
pxDNSMessageHeader = ipPOINTER_CAST( DNSMessage_t *, pucUDPPayloadBuffer ); pxDNSMessageHeader = ipPOINTER_CAST( DNSMessage_t *, pucUDPPayloadBuffer );
/* Introduce a do {} while (0) to allow the use of breaks. */ /* Introduce a do {} while (0) to allow the use of breaks. */
@ -1131,7 +1154,8 @@ uint16_t usType = 0U;
/* Check for a malformed response. */ /* Check for a malformed response. */
if( uxResult == 0U ) if( uxResult == 0U )
{ {
return dnsPARSE_ERROR; xReturn = pdFALSE;
break;
} }
uxBytesRead += uxResult; uxBytesRead += uxResult;
pucByte = &( pucByte[ uxResult ] ); pucByte = &( pucByte[ uxResult ] );
@ -1147,7 +1171,8 @@ uint16_t usType = 0U;
/* Check for a malformed response. */ /* Check for a malformed response. */
if( uxResult == 0U ) if( uxResult == 0U )
{ {
return dnsPARSE_ERROR; xReturn = pdFALSE;
break;
} }
uxBytesRead += uxResult; uxBytesRead += uxResult;
pucByte = &( pucByte[ uxResult ] ); pucByte = &( pucByte[ uxResult ] );
@ -1171,18 +1196,26 @@ uint16_t usType = 0U;
} }
else else
{ {
return dnsPARSE_ERROR; xReturn = pdFALSE;
break;
} }
} }
if( xReturn == pdFALSE )
{
/* No need to proceed. Break out of the do-while loop. */
break;
}
/* Search through the answer records. */ /* Search through the answer records. */
pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers ); pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers );
if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS ) if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
{ {
const uint16_t usCount = ( uint16_t ) ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY; const uint16_t usCount = ( uint16_t ) ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY;
uint16_t usNumARecordsStored = 0;
for( x = 0U; ( x < pxDNSMessageHeader->usAnswers ) && ( x < usCount ); x++ ) for( x = 0U; ( x < pxDNSMessageHeader->usAnswers ) && ( usNumARecordsStored < usCount ); x++ )
{ {
BaseType_t xDoAccept; BaseType_t xDoAccept;
@ -1192,7 +1225,8 @@ uint16_t usType = 0U;
/* Check for a malformed response. */ /* Check for a malformed response. */
if( uxResult == 0U ) if( uxResult == 0U )
{ {
return dnsPARSE_ERROR; xReturn = pdFALSE;
break;
} }
uxBytesRead += uxResult; uxBytesRead += uxResult;
@ -1203,7 +1237,8 @@ uint16_t usType = 0U;
is this an A record? */ is this an A record? */
if( uxSourceBytesRemaining < sizeof( uint16_t ) ) if( uxSourceBytesRemaining < sizeof( uint16_t ) )
{ {
return dnsPARSE_ERROR; xReturn = pdFALSE;
break;
} }
usType = usChar2u16( pucByte ); usType = usChar2u16( pucByte );
@ -1223,20 +1258,19 @@ uint16_t usType = 0U;
/* Unknown host type. */ /* Unknown host type. */
xDoAccept = pdFALSE; xDoAccept = pdFALSE;
} }
if( xDoAccept != pdFALSE ) if( xDoAccept != pdFALSE )
{ {
/* This is the required record type and is of sufficient size. */ /* 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 /* Mapping pucByte to a DNSAnswerRecord allows easy access of the
traversal. */ * fields of the structure. */
pxDNSAnswerRecord = ipPOINTER_CAST( DNSAnswerRecord_t *, pucByte ); pxDNSAnswerRecord = ipPOINTER_CAST( DNSAnswerRecord_t *, pucByte );
/* Sanity check the data length of an IPv4 answer. */ /* Sanity check the data length of an IPv4 answer. */
if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == ( uint16_t ) sizeof( uint32_t ) ) if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == ( uint16_t ) sizeof( uint32_t ) )
{ {
/* Copy the IP address out of the record. */ /* Copy the IP address out of the record. Using different pointers
/* MISRA c 2012 rule 21.15 relaxed here since this seems * to copy only the portion we want is intentional here. */
to be the least cumbersome way to get the IP address
from the record. */
( void ) memcpy( &( ulIPAddress ), ( void ) memcpy( &( ulIPAddress ),
&( pucByte[ sizeof( DNSAnswerRecord_t ) ] ), &( pucByte[ sizeof( DNSAnswerRecord_t ) ] ),
sizeof( uint32_t ) ); sizeof( uint32_t ) );
@ -1254,18 +1288,22 @@ uint16_t usType = 0U;
#endif /* ipconfigDNS_USE_CALLBACKS == 1 */ #endif /* ipconfigDNS_USE_CALLBACKS == 1 */
#if( ipconfigUSE_DNS_CACHE == 1 ) #if( ipconfigUSE_DNS_CACHE == 1 )
{ {
char cBuffer[ 16 ];
/* The reply will only be stored in the DNS cache when the /* The reply will only be stored in the DNS cache when the
request was issued by this device. */ request was issued by this device. */
if( xDoStore != pdFALSE ) if( xDoStore != pdFALSE )
{ {
( void ) prvProcessDNSCache( pcName, &ulIPAddress, pxDNSAnswerRecord->ulTTL, 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. */ /* Show what has happened. */
FreeRTOS_printf( ( "DNS[0x%04lX]: The answer to '%s' (%lxip) will%s be stored\n", FreeRTOS_printf( ( "DNS[0x%04lX]: The answer to '%s' (%s) will%s be stored\n",
( UBaseType_t ) pxDNSMessageHeader->usIdentifier, ( UBaseType_t ) pxDNSMessageHeader->usIdentifier,
pcName, pcName,
( UBaseType_t ) FreeRTOS_ntohl( ulIPAddress ), cBuffer,
( xDoStore != 0 ) ? "" : " NOT" ) ); ( xDoStore != 0 ) ? "" : " NOT" ) );
} }
#endif /* ipconfigUSE_DNS_CACHE */ #endif /* ipconfigUSE_DNS_CACHE */
@ -1278,9 +1316,7 @@ uint16_t usType = 0U;
{ {
/* It's not an A record, so skip it. Get the header location /* It's not an A record, so skip it. Get the header location
and then jump over the header. */ and then jump over the header. */
/* Cast the response to DNSAnswerRecord for easy access to fields of the DNS response. */
/* 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 ); pxDNSAnswerRecord = ipPOINTER_CAST( DNSAnswerRecord_t *, pucByte );
pucByte = &( pucByte[ sizeof( DNSAnswerRecord_t ) ] ); pucByte = &( pucByte[ sizeof( DNSAnswerRecord_t ) ] );
@ -1298,7 +1334,8 @@ uint16_t usType = 0U;
else else
{ {
/* Malformed response. */ /* Malformed response. */
return dnsPARSE_ERROR; xReturn = pdFALSE;
break;
} }
} }
else else
@ -1391,12 +1428,23 @@ uint16_t usType = 0U;
#endif /* ipconfigUSE_LLMNR == 1 */ #endif /* ipconfigUSE_LLMNR == 1 */
( void ) uxBytesRead; ( void ) uxBytesRead;
} while( ipFALSE_BOOL ); } 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. */ /* Do not return a valid IP-address in case the reply was not expected. */
ulIPAddress = 0UL; ulIPAddress = 0UL;
} }
else
{
/* The IP-address found will be returned. */
}
#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 ) #if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
( void ) xDoStore; ( void ) xDoStore;
#endif #endif
@ -1567,9 +1615,11 @@ BaseType_t xReturn;
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
if( ( xSocket == FREERTOS_INVALID_SOCKET ) || ( xSocket == NULL ) ) if( ( xSocket == FREERTOS_INVALID_SOCKET ) || ( xSocket == NULL ) )
{ {
return NULL; /* There was an error, return NULL. */
xSocket = NULL;
} }
else
{
/* Auto bind the port. */ /* Auto bind the port. */
xAddress.sin_port = 0U; xAddress.sin_port = 0U;
xReturn = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) ); xReturn = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
@ -1584,6 +1634,7 @@ BaseType_t xReturn;
{ {
/* The send and receive timeouts will be set later on. */ /* The send and receive timeouts will be set later on. */
} }
}
return xSocket; return xSocket;
} }
@ -1651,9 +1702,6 @@ BaseType_t xReturn;
uint32_t ulIPAddressIndex = 0; uint32_t ulIPAddressIndex = 0;
static BaseType_t xFreeEntry = 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 ) ); configASSERT( ( pcName != NULL ) );
/* For each entry in the DNS cache table. */ /* For each entry in the DNS cache table. */
@ -1736,7 +1784,7 @@ BaseType_t xReturn;
xDNSCache[ xFreeEntry ].ucCurrentIPAddress = 0; xDNSCache[ xFreeEntry ].ucCurrentIPAddress = 0;
/* Initialize all remaining IP addresses in this entry to 0 */ /* Initialize all remaining IP addresses in this entry to 0 */
memset( &xDNSCache[ xFreeEntry ].ulIPAddresses[ 1 ], ( void ) memset( &xDNSCache[ xFreeEntry ].ulIPAddresses[ 1 ],
0, 0,
sizeof( xDNSCache[ xFreeEntry ].ulIPAddresses[ 1 ] ) * sizeof( xDNSCache[ xFreeEntry ].ulIPAddresses[ 1 ] ) *
( ( uint32_t ) ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY - 1U ) ); ( ( uint32_t ) ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY - 1U ) );

View File

@ -798,7 +798,7 @@ const TickType_t xDontBlock = ( TickType_t ) 0;
iptraceNETWORK_DOWN(); iptraceNETWORK_DOWN();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Utility function. Process Network Down event from ISR. */
BaseType_t FreeRTOS_NetworkDownFromISR( void ) BaseType_t FreeRTOS_NetworkDownFromISR( void )
{ {
static const IPStackEvent_t xNetworkDownEvent = { eNetworkDownEvent, NULL }; static const IPStackEvent_t xNetworkDownEvent = { eNetworkDownEvent, NULL };
@ -1288,6 +1288,7 @@ eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucE
eFrameProcessingResult_t eReturn; eFrameProcessingResult_t eReturn;
const EthernetHeader_t *pxEthernetHeader; const EthernetHeader_t *pxEthernetHeader;
/* Map the buffer onto Ethernet Header struct for easy access to fields. */
pxEthernetHeader = ipPOINTER_CAST( const EthernetHeader_t *, pucEthernetBuffer ); pxEthernetHeader = ipPOINTER_CAST( const EthernetHeader_t *, pucEthernetBuffer );
if( memcmp( ipLOCAL_MAC_ADDRESS, pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 ) 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 ) ) if( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) )
{ {
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer ); 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 ); pxEthernetHeader = ipPOINTER_CAST( const EthernetHeader_t *, pxNetworkBuffer->pucEthernetBuffer );
/* The condition "eReturned == eProcessBuffer" must be true. */ /* The condition "eReturned == eProcessBuffer" must be true. */
@ -1688,9 +1691,10 @@ uint8_t ucProtocol;
if( ( uxHeaderLength > ( pxNetworkBuffer->xDataLength - ipSIZE_OF_ETH_HEADER ) ) || if( ( uxHeaderLength > ( pxNetworkBuffer->xDataLength - ipSIZE_OF_ETH_HEADER ) ) ||
( uxHeaderLength < ipSIZE_OF_IPv4_HEADER ) ) ( uxHeaderLength < ipSIZE_OF_IPv4_HEADER ) )
{ {
return eReleaseBuffer; eReturn = eReleaseBuffer;
} }
else
{
ucProtocol = pxIPPacket->xIPHeader.ucProtocol; ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
/* Check if the IP headers are acceptable and if it has our destination. */ /* Check if the IP headers are acceptable and if it has our destination. */
eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength ); eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );
@ -1725,11 +1729,13 @@ uint8_t ucProtocol;
{ {
/* 'ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS' is not set, so packets carrying /* 'ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS' is not set, so packets carrying
IP-options will be dropped. */ IP-options will be dropped. */
return eReleaseBuffer; eReturn = eReleaseBuffer;
} }
#endif #endif
} }
if( eReturn != eReleaseBuffer )
{
/* Add the IP and MAC addresses to the ARP table if they are not /* Add the IP and MAC addresses to the ARP table if they are not
already there - otherwise refresh the age of the existing already there - otherwise refresh the age of the existing
entry. */ entry. */
@ -1754,6 +1760,8 @@ uint8_t ucProtocol;
{ {
if( pxNetworkBuffer->xDataLength >= sizeof( ICMPPacket_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 ); ICMPPacket_t *pxICMPPacket = ipPOINTER_CAST( ICMPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER ) if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
{ {
@ -1771,6 +1779,9 @@ uint8_t ucProtocol;
case ipPROTOCOL_UDP : case ipPROTOCOL_UDP :
{ {
/* The IP packet contained a UDP frame. */ /* 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 ); const UDPPacket_t *pxUDPPacket = ipPOINTER_CAST( const UDPPacket_t *, pxNetworkBuffer->pucEthernetBuffer );
uint16_t usLength; uint16_t usLength;
@ -1840,6 +1851,8 @@ uint8_t ucProtocol;
break; break;
} }
} }
}
}
return eReturn; return eReturn;
} }
@ -1995,7 +2008,8 @@ uint8_t ucProtocol;
break; 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 ); pxIPPacket = ipPOINTER_CAST( const IPPacket_t *, pucEthernetBuffer );
ucVersionHeaderLength = pxIPPacket->xIPHeader.ucVersionHeaderLength; ucVersionHeaderLength = pxIPPacket->xIPHeader.ucVersionHeaderLength;
@ -2028,11 +2042,13 @@ uint8_t ucProtocol;
/* Identify the next protocol. */ /* Identify the next protocol. */
ucProtocol = pxIPPacket->xIPHeader.ucProtocol; 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 assignment results in a pointer into the protocol packet with the Ethernet
and IP headers incorrectly aligned. However, either way, the "third" and IP headers incorrectly aligned. However, either way, the "third"
protocol (Layer 3 or 4) header will be aligned, which is the convenience protocol (Layer 3 or 4) header will be aligned, which is the convenience
of this calculation. */ 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 ] ) ); pxProtPack = ipPOINTER_CAST( ProtocolPacket_t *, &( pucEthernetBuffer[ uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ] ) );
/* Switch on the Layer 3/4 protocol. */ /* Switch on the Layer 3/4 protocol. */
@ -2104,12 +2120,16 @@ uint16_t ucVersionHeaderLength;
BaseType_t location = 0; BaseType_t location = 0;
/* Introduce a do-while loop to allow use of break statements.
* Note: MISRA prohibits use of 'goto', thus replaced with breaks. */
do
{
/* Check for minimum packet size. */ /* Check for minimum packet size. */
if( uxBufferLength < sizeof( IPPacket_t ) ) if( uxBufferLength < sizeof( IPPacket_t ) )
{ {
usChecksum = ipINVALID_LENGTH; usChecksum = ipINVALID_LENGTH;
location = 1; location = 1;
goto error_exit; break;
} }
/* Parse the packet length. */ /* Parse the packet length. */
@ -2126,7 +2146,7 @@ BaseType_t location = 0;
{ {
usChecksum = ipINVALID_LENGTH; usChecksum = ipINVALID_LENGTH;
location = 2; location = 2;
goto error_exit; break;
} }
usLength = pxIPPacket->xIPHeader.usLength; usLength = pxIPPacket->xIPHeader.usLength;
usLength = FreeRTOS_ntohs( usLength ); usLength = FreeRTOS_ntohs( usLength );
@ -2134,7 +2154,7 @@ BaseType_t location = 0;
{ {
usChecksum = ipINVALID_LENGTH; usChecksum = ipINVALID_LENGTH;
location = 3; location = 3;
goto error_exit; break;
} }
/* Identify the next protocol. */ /* Identify the next protocol. */
@ -2154,7 +2174,7 @@ BaseType_t location = 0;
{ {
usChecksum = ipINVALID_LENGTH; usChecksum = ipINVALID_LENGTH;
location = 4; location = 4;
goto error_exit; break;
} }
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) ); pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) );
@ -2170,7 +2190,7 @@ BaseType_t location = 0;
{ {
usChecksum = ipINVALID_LENGTH; usChecksum = ipINVALID_LENGTH;
location = 5; location = 5;
goto error_exit; break;
} }
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) ); pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
@ -2187,7 +2207,7 @@ BaseType_t location = 0;
{ {
usChecksum = ipINVALID_LENGTH; usChecksum = ipINVALID_LENGTH;
location = 6; location = 6;
goto error_exit; break;
} }
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) ); pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
@ -2209,7 +2229,7 @@ BaseType_t location = 0;
/* Unhandled protocol, other than ICMP, IGMP, UDP, or TCP. */ /* Unhandled protocol, other than ICMP, IGMP, UDP, or TCP. */
usChecksum = ipUNHANDLED_PROTOCOL; usChecksum = ipUNHANDLED_PROTOCOL;
location = 7; location = 7;
goto error_exit; break;
} }
/* The protocol and checksum field have been identified. Check the direction /* The protocol and checksum field have been identified. Check the direction
@ -2247,7 +2267,7 @@ BaseType_t location = 0;
} }
#endif #endif
location = 8; location = 8;
goto error_exit; break;
} }
else else
{ {
@ -2274,7 +2294,7 @@ BaseType_t location = 0;
format/length */ format/length */
usChecksum = ipINVALID_LENGTH; usChecksum = ipINVALID_LENGTH;
location = 9; location = 9;
goto error_exit; break;
} }
if( ucProtocol <= ( uint8_t ) ipPROTOCOL_IGMP ) if( ucProtocol <= ( uint8_t ) ipPROTOCOL_IGMP )
{ {
@ -2344,8 +2364,7 @@ BaseType_t location = 0;
/* Nothing. */ /* Nothing. */
} }
#endif /* ipconfigHAS_DEBUG_PRINTF != 0 */ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
} while( ipFALSE_BOOL );
error_exit:
if( ( usChecksum == ipUNHANDLED_PROTOCOL ) || if( ( usChecksum == ipUNHANDLED_PROTOCOL ) ||
( usChecksum == ipINVALID_LENGTH ) ) ( usChecksum == ipINVALID_LENGTH ) )
@ -2482,7 +2501,9 @@ size_t uxDataLengthBytes = uxByteCount;
xLastSource.u8ptr = ( uint8_t * ) ( xSource.u8ptr + ( uxDataLengthBytes & ~( ( size_t ) 1 ) ) ); xLastSource.u8ptr = ( uint8_t * ) ( xSource.u8ptr + ( uxDataLengthBytes & ~( ( size_t ) 1 ) ) );
/* Half-word aligned. */ /* 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 ) while( xSource.u16ptr < xLastSource.u16ptr )
{ {
/* At least one more short. */ /* 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 ) void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend )
{ {
EthernetHeader_t *pxEthernetHeader; EthernetHeader_t *pxEthernetHeader;
@ -2554,6 +2577,7 @@ EthernetHeader_t *pxEthernetHeader;
if( pxNetworkBuffer != NULL ) if( pxNetworkBuffer != NULL )
#endif #endif
{ {
/* Map the Buffer to Ethernet Header struct for easy access to fields. */
pxEthernetHeader = ipPOINTER_CAST( EthernetHeader_t *, pxNetworkBuffer->pucEthernetBuffer ); pxEthernetHeader = ipPOINTER_CAST( EthernetHeader_t *, pxNetworkBuffer->pucEthernetBuffer );
/* Swap source and destination MAC addresses. */ /* Swap source and destination MAC addresses. */
@ -2769,7 +2793,8 @@ BaseType_t FreeRTOS_IsNetworkUp( void )
} }
#endif #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 *FreeRTOS_strerror_r( BaseType_t xErrnum, char *pcBuffer, size_t uxLength )
{ {
const char *pcName; const char *pcName;

View File

@ -874,6 +874,9 @@ NetworkBufferDescriptor_t xTempBuffer;
usPacketIdentifier++; usPacketIdentifier++;
pxIPHeader->usFragmentOffset = 0U; 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 ) #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
{ {
/* calculate the IP header checksum, in case the driver won't do that. */ /* calculate the IP header checksum, in case the driver won't do that. */
@ -899,9 +902,6 @@ NetworkBufferDescriptor_t xTempBuffer;
} }
#endif #endif
/* Important: tell NIC driver how many bytes must be sent. */
pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
/* Fill in the destination MAC addresses. */ /* Fill in the destination MAC addresses. */
( void ) memcpy( &( pxEthernetHeader->xDestinationAddress ), ( void ) memcpy( &( pxEthernetHeader->xDestinationAddress ),
&( pxEthernetHeader->xSourceAddress ), &( pxEthernetHeader->xSourceAddress ),
@ -2000,6 +2000,7 @@ int32_t lCount, lLength;
/* A txStream has been created already, see if the socket has new data for /* A txStream has been created already, see if the socket has new data for
the sliding window. the sliding window.
uxStreamBufferMidSpace() returns the distance between rxHead and rxMid. It uxStreamBufferMidSpace() returns the distance between rxHead and rxMid. It
contains new Tx data which has not been passed to the sliding window yet. 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. */ 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 /* All data between txMid and rxHead will now be passed to the sliding
window manager, so it can start transmitting them. window manager, so it can start transmitting them.
Hand over the new data to the sliding window handler. It will be 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 split-up in chunks of 1460 bytes each (or less, depending on
ipconfigTCP_MSS). */ ipconfigTCP_MSS). */
@ -2141,6 +2143,7 @@ uint16_t usLength;
/* Determine the length and the offset of the user-data sent to this /* Determine the length and the offset of the user-data sent to this
node. node.
The size of the TCP header is given in a multiple of 4-byte words (single 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 byte, needs no ntoh() translation). A shift-right 2: is the same as
(offset >> 4) * 4. */ (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 /* See if way may accept the data contents and forward it to the socket
owner. owner.
If it can't be "accept"ed it may have to be stored and send a selective 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 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 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 #ifdef FREERTOS_TCP_ENABLE_VERIFICATION
#include "aws_freertos_tcp_verification_access_tcp_define.h" #include "aws_freertos_tcp_verification_access_tcp_define.h"
#endif #endif

View File

@ -1910,8 +1910,8 @@ const int32_t l500ms = 500;
#if( ipconfigUSE_TCP_WIN == 0 ) #if( ipconfigUSE_TCP_WIN == 0 )
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 *pxWindow, uint32_t ulWindowSize ) static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t const * pxWindow, uint32_t ulWindowSize )
{ {
BaseType_t xReturn; 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 ) 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; BaseType_t xReturn;
TickType_t ulAge, ulMaxAge; TickType_t ulAge, ulMaxAge;

View File

@ -317,20 +317,25 @@ from the FreeRTOSIPConfig.h configuration header file. */
#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1 #define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
#endif #endif
/* Configuration to control whether packets with IP options,
#ifndef ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS * received over the network, should be passed up to the
#define ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS 1 * software stack OR should be dropped.
#endif * If set to 1, the stack accepts IP packets that contain IP options, but does
* not process the options (IP options are not supported).
#ifndef ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS * If set to 0, the stack will drop IP packets that contain IP options.
#define ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS 0 */
#endif
#ifndef ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS #ifndef ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS
#define ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS 1 #define ipconfigIP_PASS_PACKETS_WITH_IP_OPTIONS 1
#endif #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 #ifndef ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS
#define ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS 0 #define ipconfigUDP_PASS_ZERO_CHECKSUM_PACKETS 0
#endif #endif

View File

@ -304,6 +304,12 @@ BaseType_t FreeRTOS_IsNetworkUp( void );
UBaseType_t uxGetMinimumIPQueueSpace( void ); UBaseType_t uxGetMinimumIPQueueSpace( void );
#endif #endif
#if ( ipconfigHAS_PRINTF != 0 )
extern void vPrintResourceStats( void );
#else
#define vPrintResourceStats() do {} while( ipFALSE_BOOL )
#endif
/* /*
* Defined in FreeRTOS_Sockets.c * 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_. * //_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_.

View File

@ -1,3 +1,28 @@
/*
* 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 * dump_packets.c
* Used in the PC/Win project to dump Ethernet packets, along with some description. * Used in the PC/Win project to dump Ethernet packets, along with some description.

View File

@ -1,3 +1,28 @@
/*
* 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 * tcp_mem_stats.h
*/ */