Fix some build issues in older kernel demo projects.

Update to V2.0.7 of the TCP/IP stack:
   + Multiple security improvements and fixes in packet parsing routines, DNS
     caching, and TCP sequence number and ID generation.
   + Disable NBNS and LLMNR by default.
   + Add TCP hang protection by default.

We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
This commit is contained in:
Richard Barry
2018-08-22 21:29:21 +00:00
parent fb9de58f56
commit bdb088e66f
68 changed files with 5322 additions and 3910 deletions

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -211,7 +211,10 @@ uint32_t ulTargetProtocolAddress, ulSenderProtocolAddress;
void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress )
{
BaseType_t x, xIpEntry = -1, xMacEntry = -1, xUseEntry = 0;
BaseType_t x = 0;
BaseType_t xIpEntry = -1;
BaseType_t xMacEntry = -1;
BaseType_t xUseEntry = 0;
uint8_t ucMinAgeFound = 0U;
#if( ipconfigARP_STORES_REMOTE_ADDRESSES == 0 )
@ -599,7 +602,7 @@ ARPPacket_t *pxARPPacket;
xARPHeader.usOperation;
xARPHeader.xTargetHardwareAddress;
*/
memcpy( ( void * ) &( pxARPPacket->xEthernetHeader ), ( void * ) xDefaultPartARPPacketHeader, sizeof( xDefaultPartARPPacketHeader ) );
memcpy( ( void * ) pxARPPacket, ( void * ) xDefaultPartARPPacketHeader, sizeof( xDefaultPartARPPacketHeader ) );
memcpy( ( void * ) pxARPPacket->xEthernetHeader.xSourceAddress.ucBytes , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
memcpy( ( void * ) pxARPPacket->xARPHeader.xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -63,17 +63,17 @@
#endif
/* Codes of interest found in the DHCP options field. */
#define dhcpIPv4_ZERO_PAD_OPTION_CODE ( 0u )
#define dhcpIPv4_SUBNET_MASK_OPTION_CODE ( 1u )
#define dhcpIPv4_GATEWAY_OPTION_CODE ( 3u )
#define dhcpIPv4_DNS_SERVER_OPTIONS_CODE ( 6u )
#define dhcpIPv4_DNS_HOSTNAME_OPTIONS_CODE ( 12u )
#define dhcpIPv4_REQUEST_IP_ADDRESS_OPTION_CODE ( 50u )
#define dhcpIPv4_LEASE_TIME_OPTION_CODE ( 51u )
#define dhcpIPv4_MESSAGE_TYPE_OPTION_CODE ( 53u )
#define dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE ( 54u )
#define dhcpIPv4_PARAMETER_REQUEST_OPTION_CODE ( 55u )
#define dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE ( 61u )
#define dhcpZERO_PAD_OPTION_CODE ( 0u )
#define dhcpSUBNET_MASK_OPTION_CODE ( 1u )
#define dhcpGATEWAY_OPTION_CODE ( 3u )
#define dhcpDNS_SERVER_OPTIONS_CODE ( 6u )
#define dhcpDNS_HOSTNAME_OPTIONS_CODE ( 12u )
#define dhcpREQUEST_IP_ADDRESS_OPTION_CODE ( 50u )
#define dhcpLEASE_TIME_OPTION_CODE ( 51u )
#define dhcpMESSAGE_TYPE_OPTION_CODE ( 53u )
#define dhcpSERVER_IP_ADDRESS_OPTION_CODE ( 54u )
#define dhcpPARAMETER_REQUEST_OPTION_CODE ( 55u )
#define dhcpCLIENT_IDENTIFIER_OPTION_CODE ( 61u )
/* The four DHCP message types of interest. */
#define dhcpMESSAGE_TYPE_DISCOVER ( 1 )
@ -113,9 +113,7 @@ to ensure the walk has not gone past the end of the valid options. 2 bytes is
made up of the length byte, and minimum one byte value. */
#define dhcpMAX_OPTION_LENGTH_OF_INTEREST ( 2L )
/* Standard DHCP port numbers and magic cookie value.
DHCPv4 uses UDP port number 68 for clients and port number 67 for servers.
*/
/* Standard DHCP port numbers and magic cookie value. */
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
#define dhcpCLIENT_PORT 0x4400u
#define dhcpSERVER_PORT 0x4300u
@ -361,11 +359,19 @@ BaseType_t xGivingUp = pdFALSE;
if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
{
xDHCPData.ulTransactionId++;
xDHCPData.xDHCPTxTime = xTaskGetTickCount();
xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;
prvSendDHCPDiscover( );
FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );
xDHCPData.ulTransactionId = ipconfigRAND32( );
if( 0 != xDHCPData.ulTransactionId )
{
xDHCPData.xDHCPTxTime = xTaskGetTickCount( );
xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;
prvSendDHCPDiscover( );
FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );
}
else
{
FreeRTOS_debug_printf( ( "vDHCPProcess: failed to generate a random Transaction ID\n" ) );
}
}
else
{
@ -517,7 +523,7 @@ BaseType_t xGivingUp = pdFALSE;
{
/* xGivingUp became true either because of a time-out, or because
xApplicationDHCPHook() returned another value than 'eDHCPContinue',
meaning that the conversion is cancelled from here. */
meaning that the conversion is canceled from here. */
/* Revert to static IP address. */
taskENTER_CRITICAL();
@ -585,29 +591,24 @@ TickType_t xTimeoutTime = ( TickType_t ) 0;
static void prvInitialiseDHCP( void )
{
/* Initialise the parameters that will be set by the DHCP process. */
if( xDHCPData.ulTransactionId == 0ul )
{
xDHCPData.ulTransactionId = ipconfigRAND32();
}
else
{
xDHCPData.ulTransactionId++;
}
/* Initialise the parameters that will be set by the DHCP process. Per
https://www.ietf.org/rfc/rfc2131.txt, Transaction ID should be a random
value chosen by the client. */
xDHCPData.ulTransactionId = ipconfigRAND32();
/* Check for random number generator API failure. */
if( 0 != xDHCPData.ulTransactionId )
{
xDHCPData.xUseBroadcast = 0;
xDHCPData.ulOfferedIPAddress = 0UL;
xDHCPData.ulDHCPServerAddress = 0UL;
xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
/* Check for random number generator API failure. */
if( 0 != xDHCPData.ulTransactionId )
{
xDHCPData.xUseBroadcast = 0;
xDHCPData.ulOfferedIPAddress = 0UL;
xDHCPData.ulDHCPServerAddress = 0UL;
xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
/* Create the DHCP socket if it has not already been created. */
prvCreateDHCPSocket();
FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
}
/* Create the DHCP socket if it has not already been created. */
prvCreateDHCPSocket();
FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
}
}
/*-----------------------------------------------------------*/
@ -631,11 +632,14 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
pxDHCPMessage = ( DHCPMessage_t * ) ( pucUDPPayload );
/* Sanity check. */
if( ( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&
if( ( lBytes >= sizeof( DHCPMessage_t ) ) &&
( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&
( pxDHCPMessage->ucOpcode == ( uint8_t ) dhcpREPLY_OPCODE ) &&
( pxDHCPMessage->ulTransactionID == FreeRTOS_htonl( xDHCPData.ulTransactionId ) ) )
{
if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ), ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) ) == 0 )
if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ),
( void * ) ipLOCAL_MAC_ADDRESS,
sizeof( MACAddress_t ) ) == 0 )
{
/* None of the essential options have been processed yet. */
ulProcessed = 0ul;
@ -648,28 +652,52 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
while( pucByte < pucLastByte )
{
ucOptionCode = pucByte[ 0 ];
if( ucOptionCode == ( uint8_t ) dhcpOPTION_END_BYTE )
if( ucOptionCode == dhcpOPTION_END_BYTE )
{
/* Ready, the last byte has been seen. */
break;
}
if( ucOptionCode == ( uint8_t ) dhcpIPv4_ZERO_PAD_OPTION_CODE )
if( ucOptionCode == dhcpZERO_PAD_OPTION_CODE )
{
/* The value zero is used as a pad byte,
it is not followed by a length byte. */
pucByte += 1;
continue;
}
ucLength = pucByte[ 1 ];
pucByte += 2;
/* Stop if the response is malformed. */
if( pucByte < pucLastByte - 1 )
{
ucLength = pucByte[ 1 ];
pucByte += 2;
if( pucByte >= pucLastByte - ucLength )
{
break;
}
}
else
{
break;
}
/* In most cases, a 4-byte network-endian parameter follows,
just get it once here and use later */
memcpy( ( void * ) &( ulParameter ), ( void * ) pucByte, ( size_t ) sizeof( ulParameter ) );
just get it once here and use later. */
if( ucLength >= sizeof( ulParameter ) )
{
memcpy( ( void * ) &( ulParameter ),
( void * ) pucByte,
( size_t ) sizeof( ulParameter ) );
}
else
{
ulParameter = 0;
}
/* Option-specific handling. */
switch( ucOptionCode )
{
case dhcpIPv4_MESSAGE_TYPE_OPTION_CODE :
case dhcpMESSAGE_TYPE_OPTION_CODE :
if( *pucByte == ( uint8_t ) xExpectedMessageType )
{
@ -691,7 +719,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
}
break;
case dhcpIPv4_SUBNET_MASK_OPTION_CODE :
case dhcpSUBNET_MASK_OPTION_CODE :
if( ucLength == sizeof( uint32_t ) )
{
@ -699,9 +727,9 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
}
break;
case dhcpIPv4_GATEWAY_OPTION_CODE :
/* The DHCP server may send more than 1 gateway addresses. */
if( ucLength >= sizeof( uint32_t ) )
case dhcpGATEWAY_OPTION_CODE :
if( ucLength == sizeof( uint32_t ) )
{
/* ulProcessed is not incremented in this case
because the gateway is not essential. */
@ -709,7 +737,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
}
break;
case dhcpIPv4_DNS_SERVER_OPTIONS_CODE :
case dhcpDNS_SERVER_OPTIONS_CODE :
/* ulProcessed is not incremented in this case
because the DNS server is not essential. Only the
@ -717,7 +745,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
xNetworkAddressing.ulDNSServerAddress = ulParameter;
break;
case dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE :
case dhcpSERVER_IP_ADDRESS_OPTION_CODE :
if( ucLength == sizeof( uint32_t ) )
{
@ -738,7 +766,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
}
break;
case dhcpIPv4_LEASE_TIME_OPTION_CODE :
case dhcpLEASE_TIME_OPTION_CODE :
if( ucLength == sizeof( xDHCPData.ulLeaseTime ) )
{
@ -789,7 +817,7 @@ const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct
}
FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );
} /* if( lBytes > 0 ) */
}
return xReturn;
}
@ -825,9 +853,6 @@ uint8_t *pucUDPPayloadBuffer;
pxDHCPMessage->ucOpcode = ( uint8_t ) xOpcode;
pxDHCPMessage->ucAddressType = ( uint8_t ) dhcpADDRESS_TYPE_ETHERNET;
pxDHCPMessage->ucAddressLength = ( uint8_t ) dhcpETHERNET_ADDRESS_LENGTH;
/* ulTransactionID doesn't really need a htonl() translation, but when DHCP
times out, it is nicer to see an increasing number in this ID field */
pxDHCPMessage->ulTransactionID = FreeRTOS_htonl( xDHCPData.ulTransactionId );
pxDHCPMessage->ulDHCPCookie = ( uint32_t ) dhcpCOOKIE;
if( xDHCPData.xUseBroadcast != pdFALSE )
@ -851,7 +876,7 @@ uint8_t *pucUDPPayloadBuffer;
/* Point to where the OPTION_END was stored to add data. */
pucPtr = &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + ( *pxOptionsArraySize - 1 ) ] );
pucPtr[ 0 ] = dhcpIPv4_DNS_HOSTNAME_OPTIONS_CODE;
pucPtr[ 0 ] = dhcpDNS_HOSTNAME_OPTIONS_CODE;
pucPtr[ 1 ] = ( uint8_t ) xNameLength;
memcpy( ( void *) ( pucPtr + 2 ), pucHostName, xNameLength );
pucPtr[ 2 + xNameLength ] = dhcpOPTION_END_BYTE;
@ -880,15 +905,15 @@ static const uint8_t ucDHCPRequestOptions[] =
/* Do not change the ordering without also changing
dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and
dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */
dhcpIPv4_MESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpIPv4_REQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
dhcpIPv4_SERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
dhcpOPTION_END_BYTE
};
size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, ( uint8_t ) dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );
/* Copy in the IP address being requested. */
memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpREQUESTED_IP_ADDRESS_OFFSET ] ),
@ -917,14 +942,14 @@ struct freertos_sockaddr xAddress;
static const uint8_t ucDHCPDiscoverOptions[] =
{
/* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */
dhcpIPv4_MESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
dhcpIPv4_CLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpIPv4_PARAMETER_REQUEST_OPTION_CODE, 3, dhcpIPv4_SUBNET_MASK_OPTION_CODE, dhcpIPv4_GATEWAY_OPTION_CODE, dhcpIPv4_DNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, dhcpDNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
dhcpOPTION_END_BYTE
};
size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, ( uint8_t ) dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );
pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );
FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
iptraceSENDING_DHCP_DISCOVER();

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -47,17 +47,17 @@
#if( ipconfigUSE_DNS != 0 )
#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
#define dnsDNS_PORT 0x3500u
#define dnsONE_QUESTION 0x0100u
#define dnsOUTGOING_FLAGS 0x0001u /* Standard query. */
#define dnsRX_FLAGS_MASK 0x0f80u /* The bits of interest in the flags field of incoming DNS messages. */
#define dnsEXPECTED_RX_FLAGS 0x0080u /* Should be a response, without any errors. */
#define dnsDNS_PORT 0x3500
#define dnsONE_QUESTION 0x0100
#define dnsOUTGOING_FLAGS 0x0001 /* Standard query. */
#define dnsRX_FLAGS_MASK 0x0f80 /* The bits of interest in the flags field of incoming DNS messages. */
#define dnsEXPECTED_RX_FLAGS 0x0080 /* Should be a response, without any errors. */
#else
#define dnsDNS_PORT 0x0035u
#define dnsONE_QUESTION 0x0001u
#define dnsOUTGOING_FLAGS 0x0100u /* Standard query. */
#define dnsRX_FLAGS_MASK 0x800fu /* The bits of interest in the flags field of incoming DNS messages. */
#define dnsEXPECTED_RX_FLAGS 0x8000u /* Should be a response, without any errors. */
#define dnsDNS_PORT 0x0035
#define dnsONE_QUESTION 0x0001
#define dnsOUTGOING_FLAGS 0x0100 /* Standard query. */
#define dnsRX_FLAGS_MASK 0x800f /* The bits of interest in the flags field of incoming DNS messages. */
#define dnsEXPECTED_RX_FLAGS 0x8000 /* Should be a response, without any errors. */
#endif /* ipconfigBYTE_ORDER */
@ -72,29 +72,33 @@ name field is an offset to the string, rather than the string itself. */
#define dnsNAME_IS_OFFSET ( ( uint8_t ) 0xc0 )
/* NBNS flags. */
#define dnsNBNS_FLAGS_RESPONSE 0x8000u
#define dnsNBNS_FLAGS_OPCODE_MASK 0x7800u
#define dnsNBNS_FLAGS_OPCODE_QUERY 0x0000u
#define dnsNBNS_FLAGS_OPCODE_REGISTRATION 0x2800u
#define dnsNBNS_FLAGS_RESPONSE 0x8000
#define dnsNBNS_FLAGS_OPCODE_MASK 0x7800
#define dnsNBNS_FLAGS_OPCODE_QUERY 0x0000
#define dnsNBNS_FLAGS_OPCODE_REGISTRATION 0x2800
/* Host types. */
#define dnsTYPE_A_HOST 0x0001u
#define dnsCLASS_IN 0x0001u
#define dnsTYPE_A_HOST 0x01
#define dnsCLASS_IN 0x01
/* LLMNR constants. */
#define dnsLLMNR_TTL_VALUE 300000u
#define dnsLLMNR_FLAGS_IS_REPONSE 0x8000u
#define dnsLLMNR_TTL_VALUE 300000
#define dnsLLMNR_FLAGS_IS_REPONSE 0x8000
/* NBNS constants. */
#define dnsNBNS_TTL_VALUE 3600u /* 1 hour valid */
#define dnsNBNS_TYPE_NET_BIOS 0x0020u
#define dnsNBNS_CLASS_IN 0x0001u
#define dnsNBNS_NAME_FLAGS 0x6000u
#define dnsNBNS_TTL_VALUE 3600 /* 1 hour valid */
#define dnsNBNS_TYPE_NET_BIOS 0x0020
#define dnsNBNS_CLASS_IN 0x01
#define dnsNBNS_NAME_FLAGS 0x6000
#define dnsNBNS_ENCODED_NAME_LENGTH 32
/* If the queried NBNS name matches with the device's name,
the query will be responded to with these flags: */
#define dnsNBNS_QUERY_RESPONSE_FLAGS 0x8500u
#define dnsNBNS_QUERY_RESPONSE_FLAGS ( 0x8500 )
/* Flag DNS parsing errors in situations where an IPv4 address is the return
type. */
#define dnsPARSE_ERROR 0UL
/*
* Create a socket and bind it to the standard DNS port number. Return the
@ -110,12 +114,12 @@ static size_t prvCreateDNSMessage( uint8_t *pucUDPPayloadBuffer, const char *pcH
/*
* Simple routine that jumps over the NAME field of a resource record.
*/
static uint8_t *prvSkipNameField( uint8_t *pucByte );
static uint8_t *prvSkipNameField( uint8_t *pucByte, size_t xSourceLen );
/*
* Process a response packet from a DNS server.
*/
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, TickType_t xIdentifier );
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, TickType_t xIdentifier );
/*
* Prepare and send a message to a DNS server. 'xReadTimeOut_ms' will be passed as
@ -131,18 +135,19 @@ static uint32_t prvGetHostByName( const char *pcHostName, TickType_t xIdentifier
#endif
#if( ipconfigUSE_NBNS == 1 )
static portINLINE void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, uint32_t ulIPAddress );
static portINLINE void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, uint32_t ulIPAddress );
#endif /* ipconfigUSE_NBNS */
#if( ipconfigUSE_DNS_CACHE == 1 )
static uint8_t *prvReadNameField( uint8_t *pucByte, char *pcName, BaseType_t xLen );
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, BaseType_t xLookUp );
static uint8_t *prvReadNameField( uint8_t *pucByte, size_t xSourceLen, char *pcName, size_t xLen );
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, uint32_t ulTTL, BaseType_t xLookUp );
typedef struct xDNS_CACHE_TABLE_ROW
{
uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
char pcName[ipconfigDNS_CACHE_NAME_LENGTH]; /* The name of the host */
uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ]; /* The name of the host */
uint32_t ulTTL; /* Time-to-Live (in seconds) from the DNS server. */
uint32_t ulTimeWhenAddedInSeconds;
} DNSCacheRow_t;
static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
@ -180,6 +185,18 @@ struct xDNSTail
#include "pack_struct_end.h"
typedef struct xDNSTail DNSTail_t;
/* DNS answer record header. */
#include "pack_struct_start.h"
struct xDNSAnswerRecord
{
uint16_t usType;
uint16_t usClass;
uint32_t ulTTL;
uint16_t usDataLength;
}
#include "pack_struct_end.h"
typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
#if( ipconfigUSE_LLMNR == 1 )
#include "pack_struct_start.h"
@ -239,7 +256,7 @@ typedef struct xDNSTail DNSTail_t;
uint32_t FreeRTOS_dnslookup( const char *pcHostName )
{
uint32_t ulIPAddress = 0UL;
prvProcessDNSCache( pcHostName, &ulIPAddress, pdTRUE );
prvProcessDNSCache( pcHostName, &ulIPAddress, 0, pdTRUE );
return ulIPAddress;
}
#endif /* ipconfigUSE_DNS_CACHE == 1 */
@ -396,64 +413,70 @@ uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName, FOnDNSEvent pCallback
#endif
{
uint32_t ulIPAddress = 0UL;
static uint16_t usIdentifier = 0u;
TickType_t xReadTimeOut_ms = 1200U;
/* Generate a unique identifier for this query. Keep it in a local variable
as gethostbyname() may be called from different threads */
TickType_t xIdentifier = ( TickType_t )usIdentifier++;
TickType_t xReadTimeOut_ms = ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME;
TickType_t xIdentifier = 0;
/* If the supplied hostname is IP address, convert it to uint32_t
and return. */
#if( ipconfigINCLUDE_FULL_INET_ADDR == 1 )
{
ulIPAddress = FreeRTOS_inet_addr( pcHostName );
}
#endif /* ipconfigINCLUDE_FULL_INET_ADDR == 1 */
/* If the supplied hostname is IP address, convert it to uint32_t
and return. */
#if( ipconfigINCLUDE_FULL_INET_ADDR == 1 )
{
ulIPAddress = FreeRTOS_inet_addr( pcHostName );
}
#endif /* ipconfigINCLUDE_FULL_INET_ADDR == 1 */
/* If a DNS cache is used then check the cache before issuing another DNS
request. */
#if( ipconfigUSE_DNS_CACHE == 1 )
{
if( ulIPAddress == 0UL )
{
ulIPAddress = FreeRTOS_dnslookup( pcHostName );
if( ulIPAddress != 0 )
{
FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) );
}
else
{
/* prvGetHostByName will be called to start a DNS lookup */
}
}
}
#endif /* ipconfigUSE_DNS_CACHE == 1 */
/* If a DNS cache is used then check the cache before issuing another DNS
request. */
#if( ipconfigUSE_DNS_CACHE == 1 )
{
if( ulIPAddress == 0UL )
{
ulIPAddress = FreeRTOS_dnslookup( pcHostName );
if( ulIPAddress != 0 )
{
FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) );
}
else
{
/* prvGetHostByName will be called to start a DNS lookup */
}
}
}
#endif /* ipconfigUSE_DNS_CACHE == 1 */
#if( ipconfigDNS_USE_CALLBACKS != 0 )
{
if( pCallback != NULL )
{
if( ulIPAddress == 0UL )
{
/* The user has provided a callback function, so do not block on recvfrom() */
xReadTimeOut_ms = 0;
vDNSSetCallBack( pcHostName, pvSearchID, pCallback, xTimeout, ( TickType_t ) xIdentifier );
}
else
{
/* The IP address is known, do the call-back now. */
pCallback( pcHostName, pvSearchID, ulIPAddress );
}
}
}
#endif
/* Generate a unique identifier. */
if( 0 == ulIPAddress )
{
xIdentifier = ( TickType_t )ipconfigRAND32( );
}
if( ulIPAddress == 0UL)
{
ulIPAddress = prvGetHostByName( pcHostName, xIdentifier, xReadTimeOut_ms );
}
#if( ipconfigDNS_USE_CALLBACKS != 0 )
{
if( pCallback != NULL )
{
if( ulIPAddress == 0UL )
{
/* The user has provided a callback function, so do not block on recvfrom() */
if( 0 != xIdentifier )
{
xReadTimeOut_ms = 0;
vDNSSetCallBack( pcHostName, pvSearchID, pCallback, xTimeout, ( TickType_t )xIdentifier );
}
}
else
{
/* The IP address is known, do the call-back now. */
pCallback( pcHostName, pvSearchID, ulIPAddress );
}
}
}
#endif
return ulIPAddress;
if( ulIPAddress == 0UL && 0 != xIdentifier )
{
ulIPAddress = prvGetHostByName( pcHostName, xIdentifier, xReadTimeOut_ms );
}
return ulIPAddress;
}
/*-----------------------------------------------------------*/
@ -467,7 +490,7 @@ uint32_t ulAddressLength = sizeof( struct freertos_sockaddr );
BaseType_t xAttempt;
int32_t lBytes;
size_t xPayloadLength, xExpectedPayloadLength;
TickType_t xWriteTimeOut_ms = 100U;
TickType_t xWriteTimeOut_ms = ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME;
#if( ipconfigUSE_LLMNR == 1 )
BaseType_t bHasDot = pdFALSE;
@ -544,7 +567,7 @@ TickType_t xWriteTimeOut_ms = 100U;
if( lBytes > 0 )
{
/* The reply was received. Process it. */
ulIPAddress = prvParseDNSReply( pucUDPPayloadBuffer, xIdentifier );
ulIPAddress = prvParseDNSReply( pucUDPPayloadBuffer, lBytes, xIdentifier );
/* Finished with the buffer. The zero copy interface
is being used, so the buffer must be freed by the
@ -649,33 +672,74 @@ static const DNSMessage_t xDefaultPartDNSHeader =
#if( ipconfigUSE_DNS_CACHE == 1 )
static uint8_t *prvReadNameField( uint8_t *pucByte, char *pcName, BaseType_t xLen )
static uint8_t *prvReadNameField( uint8_t *pucByte, size_t xSourceLen, char *pcName, size_t xDestLen )
{
BaseType_t xNameLen = 0;
size_t xNameLen = 0;
BaseType_t xCount;
if( 0 == xSourceLen )
{
return NULL;
}
/* Determine if the name is the fully coded name, or an offset to the name
elsewhere in the message. */
if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
{
/* Jump over the two byte offset. */
pucByte += sizeof( uint16_t );
if( xSourceLen > sizeof( uint16_t ) )
{
pucByte += sizeof( uint16_t );
}
else
{
pucByte = NULL;
}
}
else
{
/* pucByte points to the full name. Walk over the string. */
while( *pucByte != 0x00 )
/* pucByte points to the full name. Walk over the string. */
while( NULL != pucByte && *pucByte != 0x00 && xSourceLen > 1 )
{
BaseType_t xCount;
if( xNameLen && xNameLen < xLen - 1 )
pcName[xNameLen++] = '.';
for( xCount = *(pucByte++); xCount--; pucByte++ )
/* If this is not the first time through the loop, then add a
separator in the output. */
if( xNameLen > 0 && xNameLen < xDestLen - 1 )
{
pcName[ xNameLen++ ] = '.';
}
/* Process the first/next sub-string. */
for( xCount = *(pucByte++), xSourceLen--;
xCount-- && xSourceLen > 1;
pucByte++, xSourceLen-- )
{
if( xNameLen < xLen - 1 )
pcName[xNameLen++] = *( ( char * ) pucByte );
if( xNameLen < xDestLen - 1 )
{
pcName[ xNameLen++ ] = *( ( char * )pucByte );
}
else
{
/* DNS name is too big for the provided buffer. */
pucByte = NULL;
break;
}
}
}
pucByte++;
/* Confirm that a fully formed name was found. */
if( NULL != pucByte )
{
if( 0x00 == *pucByte )
{
pucByte++;
xSourceLen--;
pcName[ xNameLen++ ] = '\0';
}
else
{
pucByte = NULL;
}
}
}
return pucByte;
@ -683,27 +747,60 @@ static const DNSMessage_t xDefaultPartDNSHeader =
#endif /* ipconfigUSE_DNS_CACHE == 1 */
/*-----------------------------------------------------------*/
static uint8_t *prvSkipNameField( uint8_t *pucByte )
static uint8_t *prvSkipNameField( uint8_t *pucByte, size_t xSourceLen )
{
/* Determine if the name is the fully coded name, or an offset to the name
size_t xChunkLength;
if( 0 == xSourceLen )
{
return NULL;
}
/* Determine if the name is the fully coded name, or an offset to the name
elsewhere in the message. */
if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
{
/* Jump over the two byte offset. */
pucByte += sizeof( uint16_t );
if( xSourceLen > sizeof( uint16_t ) )
{
pucByte += sizeof( uint16_t );
}
else
{
pucByte = NULL;
}
}
else
{
/* pucByte points to the full name. Walk over the string. */
while( *pucByte != 0x00 )
/* pucByte points to the full name. Walk over the string. */
while( *pucByte != 0x00 && xSourceLen > 1 )
{
/* The number of bytes to jump for each name section is stored in the byte
before the name section. */
pucByte += ( *pucByte + 1 );
xChunkLength = *pucByte + 1;
if( xSourceLen > xChunkLength )
{
xSourceLen -= xChunkLength;
pucByte += xChunkLength;
}
else
{
pucByte = NULL;
break;
}
}
pucByte++;
/* Confirm that a fully formed name was found. */
if( NULL != pucByte )
{
if( 0x00 == *pucByte )
{
pucByte++;
}
else
{
pucByte = NULL;
}
}
}
return pucByte;
@ -712,10 +809,25 @@ static uint8_t *prvSkipNameField( uint8_t *pucByte )
uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
{
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
uint8_t *pucUDPPayloadBuffer;
size_t xPlayloadBufferLength;
DNSMessage_t *pxDNSMessageHeader;
prvParseDNSReply( pucUDPPayloadBuffer, ( uint32_t ) pxDNSMessageHeader->usIdentifier );
xPlayloadBufferLength = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
if ( xPlayloadBufferLength < sizeof( DNSMessage_t ) )
{
return pdFAIL;
}
pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t ) )
{
prvParseDNSReply( pucUDPPayloadBuffer,
xPlayloadBufferLength,
( uint32_t )pxDNSMessageHeader->usIdentifier );
}
/* The packet was not consumed. */
return pdFAIL;
@ -727,9 +839,14 @@ DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
uint32_t ulNBNSHandlePacket (NetworkBufferDescriptor_t *pxNetworkBuffer )
{
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( *pxUDPPacket );
uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
prvTreatNBNS( pucUDPPayloadBuffer, pxUDPPacket->xIPHeader.ulSourceIPAddress );
if( pxNetworkBuffer->xDataLength > sizeof( UDPPacket_t) )
{
prvTreatNBNS( pucUDPPayloadBuffer,
pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ),
pxUDPPacket->xIPHeader.ulSourceIPAddress );
}
/* The packet was not consumed. */
return pdFAIL;
@ -738,28 +855,42 @@ DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
#endif /* ipconfigUSE_NBNS */
/*-----------------------------------------------------------*/
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, TickType_t xIdentifier )
static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, TickType_t xIdentifier )
{
DNSMessage_t *pxDNSMessageHeader;
DNSAnswerRecord_t *pxDNSAnswerRecord;
uint32_t ulIPAddress = 0UL;
#if( ipconfigUSE_LLMNR == 1 )
char *pcRequestedName = NULL;
#endif
uint8_t *pucByte;
size_t xSourceBytesRemaining;
uint16_t x, usDataLength, usQuestions;
#if( ipconfigUSE_LLMNR == 1 )
uint16_t usType = 0, usClass = 0;
#endif
#if( ipconfigUSE_DNS_CACHE == 1 )
char pcName[128] = ""; /*_RB_ What is the significance of 128? Probably too big to go on the stack for a small MCU but don't know how else it could be made re-entrant. Might be necessary. */
char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ] = "";
#endif
/* Ensure that the buffer is of at least minimal DNS message length. */
if( xBufferLength < sizeof( DNSMessage_t ) )
{
return dnsPARSE_ERROR;
}
else
{
xSourceBytesRemaining = xBufferLength;
}
/* Parse the DNS message header. */
pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
if( pxDNSMessageHeader->usIdentifier == ( uint16_t ) xIdentifier )
{
/* Start at the first byte after the header. */
pucByte = pucUDPPayloadBuffer + sizeof( DNSMessage_t );
xSourceBytesRemaining -= sizeof( DNSMessage_t );
/* Skip any question records. */
usQuestions = FreeRTOS_ntohs( pxDNSMessageHeader->usQuestions );
@ -777,56 +908,100 @@ uint16_t x, usDataLength, usQuestions;
#if( ipconfigUSE_DNS_CACHE == 1 )
if( x == 0 )
{
pucByte = prvReadNameField( pucByte, pcName, sizeof( pcName ) );
pucByte = prvReadNameField( pucByte,
xSourceBytesRemaining,
pcName,
sizeof( pcName ) );
/* Check for a malformed response. */
if( NULL == pucByte )
{
return dnsPARSE_ERROR;
}
else
{
xSourceBytesRemaining = ( pucUDPPayloadBuffer + xBufferLength ) - pucByte;
}
}
else
#endif /* ipconfigUSE_DNS_CACHE */
{
/* Skip the variable length pcName field. */
pucByte = prvSkipNameField( pucByte );
}
pucByte = prvSkipNameField( pucByte,
xSourceBytesRemaining );
/* Check for a malformed response. */
if( NULL == pucByte )
{
return dnsPARSE_ERROR;
}
else
{
xSourceBytesRemaining = pucUDPPayloadBuffer + xBufferLength - pucByte;
}
}
#if( ipconfigUSE_LLMNR == 1 )
{
/* usChar2u16 returns value in host endianness. */
usType = usChar2u16( pucByte );
usClass = usChar2u16( pucByte + 2 );
}
#endif /* ipconfigUSE_LLMNR */
/* Check the remaining buffer size. */
if( xSourceBytesRemaining >= sizeof( uint32_t ) )
{
#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 += sizeof( uint32_t );
/* Skip the type and class fields. */
pucByte += sizeof( uint32_t );
xSourceBytesRemaining -= sizeof( uint32_t );
}
else
{
/* Malformed response. */
return dnsPARSE_ERROR;
}
}
/* Search through the answers records. */
/* Search through the answer records. */
pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers );
if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
{
for( x = 0; x < pxDNSMessageHeader->usAnswers; x++ )
{
pucByte = prvSkipNameField( pucByte );
pucByte = prvSkipNameField( pucByte,
xSourceBytesRemaining );
/* Is the type field that of an A record? */
if( usChar2u16( pucByte ) == dnsTYPE_A_HOST )
/* Check for a malformed response. */
if( NULL == pucByte )
{
return dnsPARSE_ERROR;
}
else
{
xSourceBytesRemaining = pucUDPPayloadBuffer + xBufferLength - pucByte;
}
/* Is there enough data for an IPv4 A record answer and, if so,
is this an A record? */
if( xSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) &&
usChar2u16( pucByte ) == dnsTYPE_A_HOST )
{
/* This is the required record. Skip the type, class, and
time to live fields, plus the first byte of the data
length. */
pucByte += ( sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint8_t ) );
/* This is the required record type and is of sufficient size. */
pxDNSAnswerRecord = ( DNSAnswerRecord_t * )pucByte;
/* Sanity check the data length. */
if( ( size_t ) *pucByte == sizeof( uint32_t ) )
/* Sanity check the data length of an IPv4 answer. */
if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == sizeof( uint32_t ) )
{
/* Skip the second byte of the length. */
pucByte++;
/* Copy the IP address out of the record. */
memcpy( ( void * ) &ulIPAddress, ( void * ) pucByte, sizeof( uint32_t ) );
memcpy( &ulIPAddress,
pucByte + sizeof( DNSAnswerRecord_t ),
sizeof( uint32_t ) );
#if( ipconfigUSE_DNS_CACHE == 1 )
{
prvProcessDNSCache( pcName, &ulIPAddress, pdFALSE );
prvProcessDNSCache( pcName, &ulIPAddress, pxDNSAnswerRecord->ulTTL, pdFALSE );
}
#endif /* ipconfigUSE_DNS_CACHE */
#if( ipconfigDNS_USE_CALLBACKS != 0 )
@ -837,24 +1012,37 @@ uint16_t x, usDataLength, usQuestions;
#endif /* ipconfigDNS_USE_CALLBACKS != 0 */
}
pucByte += sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t );
xSourceBytesRemaining -= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) );
break;
}
else
else if( xSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) )
{
/* Skip the type, class and time to live fields. */
pucByte += ( sizeof( uint32_t ) + sizeof( uint32_t ) );
/* It's not an A record, so skip it. Get the header location
and then jump over the header. */
pxDNSAnswerRecord = ( DNSAnswerRecord_t * )pucByte;
pucByte += sizeof( DNSAnswerRecord_t );
xSourceBytesRemaining -= sizeof( DNSAnswerRecord_t );
/* Determine the length of the answer data from the header. */
usDataLength = FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength );
/* Determine the length of the data in the field. */
memcpy( ( void * ) &usDataLength, ( void * ) pucByte, sizeof( uint16_t ) );
usDataLength = FreeRTOS_ntohs( usDataLength );
/* Jump over the data length bytes, and the data itself. */
pucByte += usDataLength + sizeof( uint16_t );
/* Jump over the answer. */
if( xSourceBytesRemaining >= usDataLength )
{
pucByte += usDataLength;
xSourceBytesRemaining -= usDataLength;
}
else
{
/* Malformed response. */
return dnsPARSE_ERROR;
}
}
}
}
#if( ipconfigUSE_LLMNR == 1 )
else if( ( usQuestions != ( uint16_t )0u ) && ( usType == ( uint16_t )dnsTYPE_A_HOST ) && ( usClass == ( uint16_t )dnsCLASS_IN ) )
else if( usQuestions && ( usType == dnsTYPE_A_HOST ) && ( usClass == dnsCLASS_IN ) )
{
/* If this is not a reply to our DNS request, it might an LLMNR
request. */
@ -867,7 +1055,7 @@ uint16_t x, usDataLength, usQuestions;
if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
{
BaseType_t xDataLength = pxNetworkBuffer->xDataLength + sizeof( UDPHeader_t ) +
BaseType_t xDataLength = xBufferLength + sizeof( UDPHeader_t ) +
sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
/* The field xDataLength was set to the length of the UDP payload.
@ -900,7 +1088,7 @@ uint16_t x, usDataLength, usQuestions;
{
pxAnswer = (LLMNRAnswer_t *)pucByte;
/* Leave 'usIdentifier' and 'usQuestions' untouched. */
/* We leave 'usIdentifier' and 'usQuestions' untouched */
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 */
@ -935,13 +1123,20 @@ uint16_t x, usDataLength, usQuestions;
#if( ipconfigUSE_NBNS == 1 )
static void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, uint32_t ulIPAddress )
static void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer, size_t xBufferLength, uint32_t ulIPAddress )
{
uint16_t usFlags, usType, usClass;
uint8_t *pucSource, *pucTarget;
uint8_t ucByte;
uint8_t ucNBNSName[ 17 ];
/* Check for minimum buffer size. */
if( xBufferLength < sizeof( NBNSRequest_t ) )
{
return;
}
/* Read the request flags in host endianness. */
usFlags = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usFlags ) );
if( ( usFlags & dnsNBNS_FLAGS_OPCODE_MASK ) == dnsNBNS_FLAGS_OPCODE_QUERY )
@ -986,7 +1181,7 @@ uint16_t x, usDataLength, usQuestions;
{
/* If this is a response from another device,
add the name to the DNS cache */
prvProcessDNSCache( ( char * ) ucNBNSName, &ulIPAddress, pdFALSE );
prvProcessDNSCache( ( char * ) ucNBNSName, &ulIPAddress, 0, pdFALSE );
}
}
#else
@ -1012,7 +1207,6 @@ uint16_t x, usDataLength, usQuestions;
{
NetworkBufferDescriptor_t *pxNewBuffer;
BaseType_t xDataLength = pxNetworkBuffer->xDataLength + sizeof( UDPHeader_t ) +
sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
/* The field xDataLength was set to the length of the UDP payload.
@ -1127,7 +1321,7 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
/* calculate the UDP checksum for outgoing package */
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, pdTRUE );
usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, lNetLength, pdTRUE );
}
#endif
@ -1143,10 +1337,12 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
#if( ipconfigUSE_DNS_CACHE == 1 )
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, BaseType_t xLookUp )
static void prvProcessDNSCache( const char *pcName, uint32_t *pulIP, uint32_t ulTTL, BaseType_t xLookUp )
{
BaseType_t x;
BaseType_t xFound = pdFALSE;
uint32_t ulCurrentTimeSeconds =
xTaskGetTickCount( ) / portTICK_PERIOD_MS / 1000;
static BaseType_t xFreeEntry = 0;
/* For each entry in the DNS cache table. */
@ -1157,16 +1353,29 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
break;
}
if( strncmp( xDNSCache[ x ].pcName, pcName, sizeof( xDNSCache[ x ].pcName ) ) == 0 )
if( 0 == strcmp( xDNSCache[ x ].pcName, pcName ) )
{
/* Is this function called for a lookup or to add/update an IP address? */
if( xLookUp != pdFALSE )
{
*pulIP = xDNSCache[ x ].ulIPAddress;
/* Confirm that the record is still fresh. */
if( ulCurrentTimeSeconds <
xDNSCache[ x ].ulTimeWhenAddedInSeconds +
FreeRTOS_ntohl( xDNSCache[ x ].ulTTL ) )
{
*pulIP = xDNSCache[ x ].ulIPAddress;
}
else
{
/* Age out the old cached record. */
xDNSCache[ x ].pcName[ 0 ] = 0;
}
}
else
{
xDNSCache[ x ].ulIPAddress = *pulIP;
xDNSCache[ x ].ulTTL = ulTTL;
xDNSCache[ x ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
}
xFound = pdTRUE;
@ -1182,15 +1391,21 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
}
else
{
/* Called to add or update an item */
strncpy( xDNSCache[ xFreeEntry ].pcName, pcName, sizeof( xDNSCache[ xFreeEntry ].pcName ) );
xDNSCache[ xFreeEntry ].ulIPAddress = *pulIP;
/* Add or update the item. */
if( strlen( pcName ) < ipconfigDNS_CACHE_NAME_LENGTH )
{
strcpy( xDNSCache[ xFreeEntry ].pcName, pcName );
xFreeEntry++;
if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES )
{
xFreeEntry = 0;
}
xDNSCache[ xFreeEntry ].ulIPAddress = *pulIP;
xDNSCache[ xFreeEntry ].ulTTL = ulTTL;
xDNSCache[ xFreeEntry ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
xFreeEntry++;
if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES )
{
xFreeEntry = 0;
}
}
}
}
@ -1204,4 +1419,9 @@ TickType_t xTimeoutTime = pdMS_TO_TICKS( 200 );
#endif /* ipconfigUSE_DNS != 0 */
/*-----------------------------------------------------------*/
/* Provide access to private members for testing. */
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
#include "aws_freertos_tcp_test_access_dns_define.h"
#endif

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -65,9 +65,7 @@ a constant. */
/* Time delay between repeated attempts to initialise the network hardware. */
#ifndef ipINITIALISATION_RETRY_DELAY
#define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
#endif
#define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
/* Defines how often the ARP timer callback function is executed. The time is
shorted in the Windows simulator as simulated time is not real time. */
@ -186,7 +184,7 @@ static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetwor
/*
* Process incoming IP packets.
*/
static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer );
static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer );
#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
/*
@ -356,11 +354,12 @@ struct freertos_sockaddr xAddress;
/* Calculate the acceptable maximum sleep time. */
xNextIPSleep = prvCalculateSleepTime();
/* Wait until there is something to do. The event is initialised to "no
event" in case the following call exits due to a time out rather than a
message being received. */
xReceivedEvent.eEventType = eNoEvent;
xQueueReceive( xNetworkEventQueue, ( void * ) &xReceivedEvent, xNextIPSleep );
/* Wait until there is something to do. If the following call exits
* due to a time out rather than a message being received, set a
* 'NoEvent' value. */
if ( xQueueReceive( xNetworkEventQueue, ( void * ) &xReceivedEvent, xNextIPSleep ) == pdFALSE ) {
xReceivedEvent.eEventType = eNoEvent;
}
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
@ -655,14 +654,8 @@ static void prvCheckNetworkTimers( void )
#if( ipconfigUSE_TCP == 1 )
{
BaseType_t xWillSleep;
/* xStart keeps a copy of the last time this function was active,
and during every call it will be updated with xTaskGetTickCount()
'0' means: not yet initialised (although later '0' might be returned
by xTaskGetTickCount(), which is no problem). */
static TickType_t xStart = ( TickType_t ) 0;
TickType_t xTimeNow, xNextTime;
TickType_t xNextTime;
BaseType_t xCheckTCPSockets;
extern uint32_t ulNextInitialSequenceNumber;
if( uxQueueMessagesWaiting( xNetworkEventQueue ) == 0u )
{
@ -673,19 +666,6 @@ static void prvCheckNetworkTimers( void )
xWillSleep = pdFALSE;
}
xTimeNow = xTaskGetTickCount();
if( xStart != ( TickType_t ) 0 )
{
/* It is advised to increment the Initial Sequence Number every 4
microseconds which makes 250 times per ms. This will make it harder
for a third party to 'guess' our sequence number and 'take over'
a TCP connection */
ulNextInitialSequenceNumber += ipINITIAL_SEQUENCE_NUMBER_FACTOR * ( ( xTimeNow - xStart ) * portTICK_PERIOD_MS );
}
xStart = xTimeNow;
/* Sockets need to be checked if the TCP timer has expired. */
xCheckTCPSockets = prvIPTimerCheck( &xTCPTimer );
@ -823,6 +803,10 @@ void *pvReturn;
if( pxNetworkBuffer != NULL )
{
/* Set the actual packet size in case a bigger buffer was returned. */
pxNetworkBuffer->xDataLength =
sizeof( UDPPacket_t ) + xRequestedSizeBytes;
/* Leave space for the UPD header. */
pvReturn = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
}
@ -847,6 +831,11 @@ NetworkBufferDescriptor_t * pxNewBuffer;
if( pxNewBuffer != NULL )
{
/* Set the actual packet size in case a bigger buffer than requested
was returned. */
pxNewBuffer->xDataLength = xNewLength;
/* Copy the original packet information. */
pxNewBuffer->ulIPAddress = pxNetworkBuffer->ulIPAddress;
pxNewBuffer->usPort = pxNetworkBuffer->usPort;
pxNewBuffer->usBoundPort = pxNetworkBuffer->usBoundPort;
@ -997,10 +986,7 @@ BaseType_t xReturn = pdFALSE;
/* Added to prevent ARP flood to gateway. Ensure the
gateway is on the same subnet as the IP address. */
if( xNetworkAddressing.ulGatewayAddress != 0ul )
{
configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
}
configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
}
#endif /* ipconfigUSE_DHCP == 1 */
@ -1009,10 +995,13 @@ BaseType_t xReturn = pdFALSE;
memcpy( ( void * ) ipLOCAL_MAC_ADDRESS, ( void * ) ucMACAddress, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
/* Prepare the sockets interface. */
vNetworkSocketsInit();
/* Create the task that processes Ethernet and stack events. */
xReturn = xTaskCreate( prvIPTask, "IP-task", ( uint16_t ) ipconfigIP_TASK_STACK_SIZE_WORDS, NULL, ( UBaseType_t ) ipconfigIP_TASK_PRIORITY, &xIPTaskHandle );
xReturn = vNetworkSocketsInit();
if( pdTRUE == xReturn )
{
/* Create the task that processes Ethernet and stack events. */
xReturn = xTaskCreate( prvIPTask, "IP-task", ( uint16_t )ipconfigIP_TASK_STACK_SIZE_WORDS, NULL, ( UBaseType_t )ipconfigIP_TASK_PRIORITY, &xIPTaskHandle );
}
}
else
{
@ -1356,35 +1345,52 @@ void vIPNetworkUpCalls( void )
static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
EthernetHeader_t *pxEthernetHeader;
volatile eFrameProcessingResult_t eReturned; /* Volatile to prevent complier warnings when ipCONSIDER_FRAME_FOR_PROCESSING just sets it to eProcessBuffer. */
eFrameProcessingResult_t eReturned = eReleaseBuffer;
configASSERT( pxNetworkBuffer );
/* Interpret the Ethernet frame. */
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
if( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) )
{
eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
pxEthernetHeader = ( EthernetHeader_t * )( pxNetworkBuffer->pucEthernetBuffer );
if( eReturned == eProcessBuffer )
{
/* Interpret the received Ethernet packet. */
switch( pxEthernetHeader->usFrameType )
{
case ipARP_FRAME_TYPE :
/* The Ethernet frame contains an ARP packet. */
eReturned = eARPProcessPacket( ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer );
break;
if( eReturned == eProcessBuffer )
{
/* Interpret the received Ethernet packet. */
switch( pxEthernetHeader->usFrameType )
{
case ipARP_FRAME_TYPE:
/* The Ethernet frame contains an ARP packet. */
if( pxNetworkBuffer->xDataLength >= sizeof( ARPPacket_t ) )
{
eReturned = eARPProcessPacket( ( ARPPacket_t * )pxNetworkBuffer->pucEthernetBuffer );
}
else
{
eReturned = eReleaseBuffer;
}
break;
case ipIPv4_FRAME_TYPE :
/* The Ethernet frame contains an IP packet. */
eReturned = prvProcessIPPacket( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer );
break;
case ipIPv4_FRAME_TYPE:
/* The Ethernet frame contains an IP packet. */
if( pxNetworkBuffer->xDataLength >= sizeof( IPPacket_t ) )
{
eReturned = prvProcessIPPacket( ( IPPacket_t * )pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer );
}
else
{
eReturned = eReleaseBuffer;
}
break;
default :
/* No other packet types are handled. Nothing to do. */
eReturned = eReleaseBuffer;
break;
}
}
default:
/* No other packet types are handled. Nothing to do. */
eReturned = eReleaseBuffer;
break;
}
}
}
/* Perform any actions that resulted from processing the Ethernet frame. */
switch( eReturned )
@ -1433,9 +1439,9 @@ eFrameProcessingResult_t eReturn = eProcessBuffer;
This method may decrease the usage of sparse network buffers. */
uint32_t ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
/* Ensure that the incoming packet is not fragmented (fragmentation
was only supported for outgoing packets, and is not currently
not supported at all). */
/* Ensure that the incoming packet is not fragmented (only outgoing
packets can be fragmented) as these are the only handled IP frames
currently. */
if( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U )
{
/* Can not handle, fragmented packet. */
@ -1481,7 +1487,7 @@ eFrameProcessingResult_t eReturn = eProcessBuffer;
eReturn = eReleaseBuffer;
}
/* Is the upper-layer checksum (TCP/UDP/ICMP) correct? */
else if( usGenerateProtocolChecksum( ( uint8_t * )( pxNetworkBuffer->pucEthernetBuffer ), pdFALSE ) != ipCORRECT_CRC )
else if( usGenerateProtocolChecksum( ( uint8_t * )( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength, pdFALSE ) != ipCORRECT_CRC )
{
/* Protocol checksum not accepted. */
eReturn = eReleaseBuffer;
@ -1500,13 +1506,22 @@ eFrameProcessingResult_t eReturn = eProcessBuffer;
}
/*-----------------------------------------------------------*/
static eFrameProcessingResult_t prvProcessIPPacket( const IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer )
static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer )
{
eFrameProcessingResult_t eReturn;
const IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
UBaseType_t uxHeaderLength = ( UBaseType_t ) ( ( pxIPHeader->ucVersionHeaderLength & 0x0Fu ) << 2 );
uint8_t ucProtocol;
/* Bound the calculated header length: take away the Ethernet header size,
then check if the IP header is claiming to be longer than the remaining
total packet size. Also check for minimal header field length. */
if( uxHeaderLength > pxNetworkBuffer->xDataLength - ipSIZE_OF_ETH_HEADER ||
uxHeaderLength < ipSIZE_OF_IPv4_HEADER )
{
return eReleaseBuffer;
}
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
/* Check if the IP headers are acceptable and if it has our destination. */
eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );
@ -1520,15 +1535,21 @@ uint8_t ucProtocol;
* Note: IP options are mostly use in Multi-cast protocols */
const size_t optlen = ( ( size_t ) uxHeaderLength ) - ipSIZE_OF_IPv4_HEADER;
/* From: the previous start of UDP/ICMP/TCP data */
uint8_t *pucSource = ( ( uint8_t * ) pxIPHeader ) + uxHeaderLength;
uint8_t *pucSource = ( uint8_t* )(pxNetworkBuffer->pucEthernetBuffer + sizeof( EthernetHeader_t ) + uxHeaderLength);
/* To: the usual start of UDP/ICMP/TCP data at offset 20 from IP header */
uint8_t *pucTarget = ( ( uint8_t * ) pxIPHeader ) + ipSIZE_OF_IPv4_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;
memmove( pucTarget, pucSource, xMoveLen );
pxNetworkBuffer->xDataLength -= optlen;
/* Fix-up new version/header length field in IP packet. */
pxIPHeader->ucVersionHeaderLength =
( pxIPHeader->ucVersionHeaderLength & 0xF0 ) | /* High nibble is the version. */
( ( ipSIZE_OF_IPv4_HEADER >> 2 ) & 0x0F ); /* Low nibble is the header size, in bytes, divided by four. */
}
/* Add the IP and MAC addresses to the ARP table if they are not
already there - otherwise refresh the age of the existing
entry. */
@ -1552,11 +1573,18 @@ uint8_t ucProtocol;
be able to validate what it receives. */
#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
{
ICMPPacket_t *pxICMPPacket = ( ICMPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
{
eReturn = prvProcessICMPPacket( pxICMPPacket );
}
if( pxNetworkBuffer->xDataLength >= sizeof( ICMPPacket_t ) )
{
ICMPPacket_t *pxICMPPacket = ( 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;
@ -1566,23 +1594,47 @@ uint8_t ucProtocol;
/* The IP packet contained a UDP frame. */
UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
/* Note the header values required prior to the
checksum generation as the checksum pseudo header
may clobber some of these values. */
pxNetworkBuffer->xDataLength = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t );
/* HT:endian: fields in pxNetworkBuffer (usPort, ulIPAddress) were network order */
pxNetworkBuffer->usPort = pxUDPPacket->xUDPHeader.usSourcePort;
pxNetworkBuffer->ulIPAddress = pxUDPPacket->xIPHeader.ulSourceIPAddress;
/* Only proceed if the payload length indicated in the header
appears to be valid. */
if ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) )
{
/* 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.
*/
pxNetworkBuffer->xDataLength -= sizeof( UDPPacket_t );
if( ( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t ) ) <
pxNetworkBuffer->xDataLength )
{
pxNetworkBuffer->xDataLength = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) -
sizeof( UDPHeader_t );
}
/* 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. */
/* HT:endian: xProcessReceivedUDPPacket wanted network order */
if( xProcessReceivedUDPPacket( pxNetworkBuffer, pxUDPPacket->xUDPHeader.usDestinationPort ) == pdPASS )
{
eReturn = eFrameConsumed;
}
/* 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;
}
}
break;
@ -1739,7 +1791,7 @@ uint8_t ucProtocol;
#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
/*-----------------------------------------------------------*/
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, BaseType_t xOutgoingPacket )
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket )
{
uint32_t ulLength;
uint16_t usChecksum, *pusChecksum;
@ -1751,13 +1803,48 @@ uint8_t ucProtocol;
const char *pcType;
#endif
pxIPPacket = ( const IPPacket_t * ) pucEthernetBuffer;
uxIPHeaderLength = ( UBaseType_t ) ( 4u * ( pxIPPacket->xIPHeader.ucVersionHeaderLength & 0x0Fu ) ); /*_RB_ Why 4? */
pxProtPack = ( ProtocolPacket_t * ) ( pucEthernetBuffer + ( uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ) );
ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
/* Check for minimum packet size. */
if( uxBufferLength < sizeof( IPPacket_t ) )
{
return ipINVALID_LENGTH;
}
/* Parse the packet length. */
pxIPPacket = ( 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. */
uxIPHeaderLength = ( UBaseType_t )
( sizeof( uint32_t ) * ( pxIPPacket->xIPHeader.ucVersionHeaderLength & 0x0Fu ) );
/* Check for minimum packet size. */
if( uxBufferLength < sizeof( IPPacket_t ) + uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER )
{
return ipINVALID_LENGTH;
}
if( uxBufferLength < FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) )
{
return ipINVALID_LENGTH;
}
/* 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 = ( 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 )
{
return ipINVALID_LENGTH;
}
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) );
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
{
@ -1767,7 +1854,12 @@ uint8_t ucProtocol;
}
else if( ucProtocol == ( uint8_t ) ipPROTOCOL_TCP )
{
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
if( uxBufferLength < uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_TCP_HEADER )
{
return ipINVALID_LENGTH;
}
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
{
pcType = "TCP";
@ -1777,8 +1869,12 @@ uint8_t ucProtocol;
else if( ( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) ||
( ucProtocol == ( uint8_t ) ipPROTOCOL_IGMP ) )
{
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
if( uxBufferLength < uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_ICMP_HEADER )
{
return ipINVALID_LENGTH;
}
pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
#if( ipconfigHAS_DEBUG_PRINTF != 0 )
{
if( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
@ -1798,6 +1894,8 @@ uint8_t ucProtocol;
return ipUNHANDLED_PROTOCOL;
}
/* 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
@ -1844,7 +1942,7 @@ uint8_t ucProtocol;
/* And then continue at the IPv4 source and destination addresses. */
usChecksum = ( uint16_t )
( ~usGenerateChecksum( ( uint32_t ) usChecksum, ( uint8_t * )&( pxIPPacket->xIPHeader.ulSourceIPAddress ),
( size_t )( 2u * sizeof( pxIPPacket->xIPHeader.ulSourceIPAddress ) + ulLength ) ) );
( 2u * sizeof( pxIPPacket->xIPHeader.ulSourceIPAddress ) + ulLength ) ) );
/* Sum TCP header and data. */
}
@ -1897,6 +1995,39 @@ uint8_t ucProtocol;
}
/*-----------------------------------------------------------*/
/**
* This method generates a checksum for a given IPv4 header, per RFC791 (page 14).
* The checksum algorithm is decribed as:
* "[T]he 16 bit one's complement of the one's complement sum of all 16 bit words in the
* header. For purposes of computing the checksum, the value of the checksum field is zero."
*
* In a nutshell, that means that each 16-bit 'word' must be summed, after which
* the number of 'carries' (overflows) is added to the result. If that addition
* produces an overflow, that 'carry' must also be added to the final result. The final checksum
* should be the bitwise 'not' (ones-complement) of the result if the packet is
* meant to be transmitted, but this method simply returns the raw value, probably
* because when a packet is received, the checksum is verified by checking that
* ((received & calculated) == 0) without applying a bitwise 'not' to the 'calculated' checksum.
*
* This logic is optimized for microcontrollers which have limited resources, so the logic looks odd.
* It iterates over the full range of 16-bit words, but it does so by processing several 32-bit
* words at once whenever possible. Its first step is to align the memory pointer to a 32-bit boundary,
* after which it runs a fast loop to process multiple 32-bit words at once and adding their 'carries'.
* Finally, it finishes up by processing any remaining 16-bit words, and adding up all of the 'carries'.
* With 32-bit arithmetic, the number of 16-bit 'carries' produced by sequential additions can be found
* by looking at the 16 most-significant bits of the 32-bit integer, since a 32-bit int will continue
* counting up instead of overflowing after 16 bits. That is why the actual checksum calculations look like:
* union.u32 = ( uint32_t ) union.u16[ 0 ] + union.u16[ 1 ];
*
* Arguments:
* ulSum: This argument provides a value to initialize the progressive summation
* of the header's values to. It is often 0, but protocols like TCP or UDP
* can have pseudo-header fields which need to be included in the checksum.
* pucNextData: This argument contains the address of the first byte which this
* method should process. The method's memory iterator is initialized to this value.
* uxDataLengthBytes: This argument contains the number of bytes that this method
* should process.
*/
uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes )
{
xUnion32 xSum2, xSum, xTerm;
@ -2095,8 +2226,8 @@ uint32_t FreeRTOS_GetNetmask( void )
void FreeRTOS_UpdateMACAddress( const uint8_t ucMACAddress[ipMAC_ADDRESS_LENGTH_BYTES] )
{
/* Copy the MAC address at the start of the default packet header fragment. */
memcpy( ( void * )ipLOCAL_MAC_ADDRESS, ( void * )ucMACAddress, ( size_t )ipMAC_ADDRESS_LENGTH_BYTES );
/* Copy the MAC address at the start of the default packet header fragment. */
memcpy( ( void * )ipLOCAL_MAC_ADDRESS, ( void * )ucMACAddress, ( size_t )ipMAC_ADDRESS_LENGTH_BYTES );
}
/*-----------------------------------------------------------*/

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -54,18 +54,16 @@ xBoundUDPSocketsList or xBoundTCPSocketsList */
number then, depending on the FreeRTOSIPConfig.h settings, it might be that a
port number is automatically generated for the socket. Automatically generated
port numbers will be between socketAUTO_PORT_ALLOCATION_START_NUMBER and
0xffff. */
/* _HT_ thinks that the default of 0xc000 is pretty high */
0xffff.
Per https://tools.ietf.org/html/rfc6056, "the dynamic ports consist of the range
49152-65535. However, ephemeral port selection algorithms should use the whole
range 1024-65535" excluding those already in use (inbound or outbound). */
#if !defined( socketAUTO_PORT_ALLOCATION_START_NUMBER )
#define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0xc000 )
#define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0x0400 )
#endif
/* When the automatically generated port numbers overflow, the next value used
is not set back to socketAUTO_PORT_ALLOCATION_START_NUMBER because it is likely
that the first few automatically generated ports will still be in use. Instead
it is reset back to the value defined by this constant. */
#define socketAUTO_PORT_ALLOCATION_RESET_NUMBER ( ( uint16_t ) 0xc100 )
#define socketAUTO_PORT_ALLOCATION_MAX_NUMBER ( ( uint16_t ) 0xff00 )
#define socketAUTO_PORT_ALLOCATION_MAX_NUMBER ( ( uint16_t ) 0xffff )
/* The number of octets that make up an IP address. */
#define socketMAX_IP_ADDRESS_OCTETS 4u
@ -165,15 +163,6 @@ List_t xBoundUDPSocketsList;
List_t xBoundTCPSocketsList;
#endif /* ipconfigUSE_TCP == 1 */
/* Holds the next private port number to use when binding a client socket for
UDP, and if ipconfigUSE_TCP is set to 1, also TCP. UDP uses index
socketNEXT_UDP_PORT_NUMBER_INDEX and TCP uses index
socketNEXT_TCP_PORT_NUMBER_INDEX. The initial value is set to be between
socketAUTO_PORT_ALLOCATION_RESET_NUMBER and socketAUTO_PORT_ALLOCATION_MAX_NUMBER
when the IP stack is initialised. Note ipconfigRAND32() is used, which must be
seeded prior to the IP task being started. */
static uint16_t usNextPortToUse[ socketPROTOCOL_COUNT ] = { 0 };
/*-----------------------------------------------------------*/
static BaseType_t prvValidSocket( FreeRTOS_Socket_t *pxSocket, BaseType_t xProtocol, BaseType_t xIsBound )
@ -199,35 +188,17 @@ BaseType_t xReturn = pdTRUE;
}
/*-----------------------------------------------------------*/
void vNetworkSocketsInit( void )
BaseType_t vNetworkSocketsInit( void )
{
const uint32_t ulAutoPortRange = socketAUTO_PORT_ALLOCATION_MAX_NUMBER - socketAUTO_PORT_ALLOCATION_RESET_NUMBER;
uint32_t ulRandomPort;
vListInitialise( &xBoundUDPSocketsList );
vListInitialise( &xBoundUDPSocketsList );
#if( ipconfigUSE_TCP == 1 )
{
vListInitialise( &xBoundTCPSocketsList );
}
#endif /* ipconfigUSE_TCP == 1 */
/* Determine the first anonymous UDP port number to get assigned. Give it
a random value in order to avoid confusion about port numbers being used
earlier, before rebooting the device. Start with the first auto port
number, then add a random offset up to a maximum of the range of numbers. */
ulRandomPort = socketAUTO_PORT_ALLOCATION_START_NUMBER;
ulRandomPort += ( ipconfigRAND32() % ulAutoPortRange );
usNextPortToUse[ socketNEXT_UDP_PORT_NUMBER_INDEX ] = ( uint16_t ) ulRandomPort;
#if( ipconfigUSE_TCP == 1 )
{
extern uint32_t ulNextInitialSequenceNumber;
ulNextInitialSequenceNumber = ipconfigRAND32();
/* Determine the first anonymous TCP port number to get assigned. */
ulRandomPort = socketAUTO_PORT_ALLOCATION_START_NUMBER;
ulRandomPort += ( ipconfigRAND32() % ulAutoPortRange );
usNextPortToUse[ socketNEXT_TCP_PORT_NUMBER_INDEX ] = ( uint16_t ) ulRandomPort;
vListInitialise( &xBoundTCPSocketsList );
}
#endif /* ipconfigUSE_TCP == 1 */
return pdTRUE;
}
/*-----------------------------------------------------------*/
@ -261,6 +232,7 @@ FreeRTOS_Socket_t *pxSocket;
if( xType != FREERTOS_SOCK_DGRAM )
{
xReturn = pdFAIL;
configASSERT( xReturn );
}
/* In case a UDP socket is created, do not allocate space for TCP data. */
*pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xUDP );
@ -271,6 +243,7 @@ FreeRTOS_Socket_t *pxSocket;
if( xType != FREERTOS_SOCK_STREAM )
{
xReturn = pdFAIL;
configASSERT( xReturn );
}
*pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xTCP );
@ -279,6 +252,7 @@ FreeRTOS_Socket_t *pxSocket;
else
{
xReturn = pdFAIL;
configASSERT( xReturn );
}
}
/* In case configASSERT() is not used */
@ -320,7 +294,7 @@ Socket_t xReturn;
}
else
{
/* Clear the entire space to avoid nulling individual entries. */
/* Clear the entire space to avoid nulling individual entries */
memset( pxSocket, '\0', uxSocketSize );
pxSocket->xEventGroup = xEventGroup;
@ -1016,14 +990,12 @@ List_t *pxSocketList;
#if( ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 )
{
/* pxAddress will be NULL if sendto() was called on a socket without the
socket being bound to an address. In this case, automatically allocate
an address to the socket. There is a very tiny chance that the allocated
port will already be in use - if that is the case, then the check below
[pxListFindListItemWithValue()] will result in an error being returned. */
socket being bound to an address. In this case, automatically allocate
an address and port to the socket. */
if( pxAddress == NULL )
{
pxAddress = &xAddress;
/* For now, put it to zero, will be assigned later */
/* Put the port to zero to be assigned later. */
pxAddress->sin_port = 0u;
}
}
@ -1037,7 +1009,11 @@ List_t *pxSocketList;
{
if( pxAddress->sin_port == 0u )
{
pxAddress->sin_port = prvGetPrivatePortNumber( ( BaseType_t ) pxSocket->ucProtocol );
pxAddress->sin_port = prvGetPrivatePortNumber( ( BaseType_t )pxSocket->ucProtocol );
if( 0 == pxAddress->sin_port )
{
return -pdFREERTOS_ERRNO_EADDRNOTAVAIL;
}
}
/* If vSocketBind() is called from the API FreeRTOS_bind() it has been
@ -1524,7 +1500,7 @@ FreeRTOS_Socket_t *pxSocket;
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bHasInit != pdFALSE_UNSIGNED )
{
pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength = pxSocket->u.xTCP.uxRxWinSize * pxSocket->u.xTCP.usInitMSS;
pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength = pxSocket->u.xTCP.uxTxWinSize * pxSocket->u.xTCP.usInitMSS;
pxSocket->u.xTCP.xTCPWindow.xSize.ulTxWindowLength = pxSocket->u.xTCP.uxTxWinSize * pxSocket->u.xTCP.usInitMSS;
}
}
@ -1631,54 +1607,77 @@ FreeRTOS_Socket_t *pxSocket;
/*-----------------------------------------------------------*/
/* Get a free private ('anonymous') port number */
/* Find an available port number per https://tools.ietf.org/html/rfc6056. */
static uint16_t prvGetPrivatePortNumber( BaseType_t xProtocol )
{
uint16_t usResult;
BaseType_t xIndex;
const uint16_t usEphemeralPortCount =
socketAUTO_PORT_ALLOCATION_MAX_NUMBER - socketAUTO_PORT_ALLOCATION_START_NUMBER + 1;
uint16_t usIterations = usEphemeralPortCount;
uint32_t ulRandomSeed = 0;
uint16_t usResult = 0;
BaseType_t xGotZeroOnce = pdFALSE;
const List_t *pxList;
#if ipconfigUSE_TCP == 1
if( xProtocol == ( BaseType_t ) FREERTOS_IPPROTO_TCP )
{
xIndex = socketNEXT_TCP_PORT_NUMBER_INDEX;
pxList = &xBoundTCPSocketsList;
}
else
#endif
{
xIndex = socketNEXT_UDP_PORT_NUMBER_INDEX;
pxList = &xBoundUDPSocketsList;
}
/* Avoid compiler warnings if ipconfigUSE_TCP is not defined. */
( void ) xProtocol;
/* Assign the next port in the range. Has it overflowed? */
/*_RB_ This needs to be randomised rather than sequential. */
/* _HT_ Agreed, although many OS's use sequential port numbers, see
https://www.cymru.com/jtk/misc/ephemeralports.html */
for ( ;; )
{
++( usNextPortToUse[ xIndex ] );
/* Find the next available port using the random seed as a starting
point. */
do
{
/* Generate a random seed. */
ulRandomSeed = ipconfigRAND32( );
if( usNextPortToUse[ xIndex ] >= socketAUTO_PORT_ALLOCATION_MAX_NUMBER )
{
/* Don't go right back to the start of the dynamic/private port
range numbers as any persistent sockets are likely to have been
create first so the early port numbers may still be in use. */
usNextPortToUse[ xIndex ] = socketAUTO_PORT_ALLOCATION_RESET_NUMBER;
}
/* Only proceed if the random number generator succeeded. */
if( 0 == ulRandomSeed )
{
if( pdFALSE == xGotZeroOnce )
{
xGotZeroOnce = pdTRUE;
continue;
}
else
{
break;
}
}
usResult = FreeRTOS_htons( usNextPortToUse[ xIndex ] );
/* Map the random to a candidate port. */
usResult =
socketAUTO_PORT_ALLOCATION_START_NUMBER +
( ( ( uint16_t )ulRandomSeed ) % usEphemeralPortCount );
if( pxListFindListItemWithValue( pxList, ( TickType_t ) usResult ) == NULL )
{
break;
}
}
return usResult;
} /* Tested */
/* Check if there's already an open socket with the same protocol
and port. */
if( NULL == pxListFindListItemWithValue(
pxList,
( TickType_t )FreeRTOS_htons( usResult ) ) )
{
usResult = FreeRTOS_htons( usResult );
break;
}
else
{
usResult = 0;
}
usIterations--;
}
while( usIterations > 0 );
return usResult;
}
/*-----------------------------------------------------------*/
/* pxListFindListItemWithValue: find a list item in a bound socket list
@ -1889,7 +1888,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
/* This define makes it possible for network-card drivers to inspect
* UDP message and see if there is any UDP socket bound to a given port
* number.
* This is probably only useful in systems with a minimum of RAM and
* This is probably only usefull in systems with a minimum of RAM and
* when lots of anonymous broadcast messages come in
*/
BaseType_t xPortHasUDPSocket( uint16_t usPortNr )
@ -2374,9 +2373,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
{
xResult = -pdFREERTOS_ERRNO_ENOMEM;
}
else if( ( pxSocket->u.xTCP.ucTCPState == eCLOSED ) ||
( pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ) ||
( pxSocket->u.xTCP.ucTCPState == eCLOSING ) )
else if( pxSocket->u.xTCP.ucTCPState == eCLOSED )
{
xResult = -pdFREERTOS_ERRNO_ENOTCONN;
}
@ -2875,7 +2872,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
#if( ipconfigUSE_TCP == 1 )
static StreamBuffer_t *prvTCPCreateStream( FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream )
static StreamBuffer_t *prvTCPCreateStream ( FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream )
{
StreamBuffer_t *pxBuffer;
size_t uxLength;
@ -2885,26 +2882,11 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
creation, it could still be changed with setsockopt(). */
if( xIsInputStream != pdFALSE )
{
/* Flow control for input streams works with a low- and a high-water mark.
1) If the RX-space becomes less than uxLittleSpace, the flag 'bLowWater' will
be set, and a TCP window update message will be sent to the peer.
2) The data will be read from the socket by recv() and when RX-space becomes
larger than or equal to than 'uxEnoughSpace', a new TCP window update
message will be sent to the peer, and 'bLowWater' will get cleared again.
By default:
uxLittleSpace == 1/5 x uxRxStreamSize
uxEnoughSpace == 4/5 x uxRxStreamSize
How-ever it is very inefficient to make 'uxLittleSpace' smaller than the actual MSS.
*/
uxLength = pxSocket->u.xTCP.uxRxStreamSize;
if( pxSocket->u.xTCP.uxLittleSpace == 0ul )
{
pxSocket->u.xTCP.uxLittleSpace = ( 1ul * pxSocket->u.xTCP.uxRxStreamSize ) / 5u; /*_RB_ Why divide by 5? Can this be changed to a #define? */
if( ( pxSocket->u.xTCP.uxLittleSpace < pxSocket->u.xTCP.usCurMSS ) && ( pxSocket->u.xTCP.uxRxStreamSize >= 2u * pxSocket->u.xTCP.usCurMSS ) )
{
pxSocket->u.xTCP.uxLittleSpace = pxSocket->u.xTCP.usCurMSS;
}
}
if( pxSocket->u.xTCP.uxEnoughSpace == 0ul )
@ -3047,10 +3029,8 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
break;
}
if( pxSocket->u.xTCP.pxHandleReceive( (Socket_t *)pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount ) != pdFALSE )
{
uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );
}
pxSocket->u.xTCP.pxHandleReceive( (Socket_t *)pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );
uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );
}
} else
#endif /* ipconfigUSE_CALLBACKS */
@ -3378,12 +3358,13 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
char ucChildText[16] = "";
if (pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN)
{
snprintf( ucChildText, sizeof( ucChildText ), " %d/%d",
pxSocket->u.xTCP.usChildCount,
pxSocket->u.xTCP.usBacklog);
const int32_t copied_len = snprintf( ucChildText, sizeof( ucChildText ), " %d/%d",
( int ) pxSocket->u.xTCP.usChildCount,
( int ) pxSocket->u.xTCP.usBacklog);
/* These should never evaluate to false since the buffers are both shorter than 5-6 characters (<=65535) */
configASSERT( copied_len >= 0 );
configASSERT( copied_len < sizeof( ucChildText ) );
}
if( age > 999999 )
age = 999999;
FreeRTOS_printf( ( "TCP %5d %-16lxip:%5d %d/%d %-13.13s %6lu %6u%s\n",
pxSocket->usLocalPort, /* Local port on this machine */
pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine */
@ -3391,7 +3372,7 @@ void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
pxSocket->u.xTCP.rxStream != NULL,
pxSocket->u.xTCP.txStream != NULL,
FreeRTOS_GetTCPStateName( pxSocket->u.xTCP.ucTCPState ),
age,
(age > 999999 ? 999999 : age), /* Format 'age' for printing */
pxSocket->u.xTCP.usTimeout,
ucChildText ) );
/* Remove compiler warnings if FreeRTOS_debug_printf() is not defined. */

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -61,7 +61,7 @@
/* This compile-time test was moved to here because some macro's
were unknown within 'FreeRTOSIPConfigDefaults.h'. It tests whether
the defined MTU size can contain at ;east a complete TCP packet. */
the defined MTU size can contain at least a complete TCP packet. */
#if ( ( ipconfigTCP_MSS + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) > ipconfigNETWORK_MTU )
#error The ipconfigTCP_MSS setting in FreeRTOSIPConfig.h is too large.
@ -137,13 +137,6 @@ the defined MTU size can contain at ;east a complete TCP packet. */
*/
#define REDUCED_MSS_THROUGH_INTERNET ( 1400 )
/*
* Each time a new TCP connection is being made, a new Initial Sequence Number shall be used.
* The variable 'ulNextInitialSequenceNumber' will be incremented with a recommended value
* of 0x102.
*/
#define INITIAL_SEQUENCE_NUMBER_INCREMENT ( 0x102UL )
/*
* When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
* the number 5 (words) in the higher niblle of the TCP-offset byte.
@ -269,10 +262,6 @@ static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket );
*/
static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
static UBaseType_t prvTCPSetTimeStamp( BaseType_t lOffset, FreeRTOS_Socket_t *pxSocket, TCPHeader_t *pxTCPHeader );
#endif
/*
* Called from prvTCPHandleState(). Find the TCP payload data and check and
* return its length.
@ -360,12 +349,14 @@ static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocke
static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket );
#endif
/*-----------------------------------------------------------*/
/* Initial Sequence Number, i.e. the next initial sequence number that will be
used when a new connection is opened. The value should be randomized to prevent
attacks from outside (spoofing). */
uint32_t ulNextInitialSequenceNumber = 0ul;
/*
* Generate a randomized TCP Initial Sequence Number per RFC.
*/
extern uint32_t ulApplicationGetNextSequenceNumber(
uint32_t ulSourceAddress,
uint16_t usSourcePort,
uint32_t ulDestinationAddress,
uint16_t usDestinationPort );
/*-----------------------------------------------------------*/
@ -480,11 +471,11 @@ BaseType_t xReady = pdFALSE;
if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.txStream != NULL ) )
{
/* The API FreeRTOS_send() might have added data to the TX stream. Add
this data to the windowing system so it can be transmitted. */
this data to the windowing system to it can be transmitted. */
prvTCPAddTxData( pxSocket );
}
#if( ipconfigUSE_TCP_WIN == 1 )
#if ipconfigUSE_TCP_WIN == 1
{
if( pxSocket->u.xTCP.pxAckMessage != NULL )
{
@ -577,7 +568,7 @@ NetworkBufferDescriptor_t *pxNetworkBuffer;
if( pxSocket->u.xTCP.ucTCPState != eCONNECT_SYN )
{
/* The connection is in a state other than SYN. */
/* The connection is in s state other than SYN. */
pxNetworkBuffer = NULL;
/* prvTCPSendRepeated() will only create a network buffer if necessary,
@ -609,18 +600,6 @@ NetworkBufferDescriptor_t *pxNetworkBuffer;
the Ethernet address of the peer or the gateway is found. */
pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
{
/* When TCP time stamps are enabled, but they will only be applied
if the peer is outside the netmask, usually on the internet.
Packages sent on a LAN are usually too big to carry time stamps. */
if( ( ( pxSocket->u.xTCP.ulRemoteIP ^ FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) ) & xNetworkAddressing.ulNetMask ) != 0ul )
{
pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps = pdTRUE_UNSIGNED;
}
}
#endif
/* About to send a SYN packet. Call prvSetSynAckOptions() to set
the proper options: The size of MSS and whether SACK's are
allowed. */
@ -707,12 +686,15 @@ NetworkBufferDescriptor_t xTempBuffer;
if( pxNetworkBuffer == NULL )
{
memset( &xTempBuffer, '\0', sizeof( xTempBuffer ) );
pxNetworkBuffer = &xTempBuffer;
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
xTempBuffer.pxNextBuffer = NULL;
}
#endif
xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
/* A pseudo network buffer can not be released. */
xReleaseAfterSend = pdFALSE;
}
@ -903,7 +885,7 @@ NetworkBufferDescriptor_t xTempBuffer;
pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
/* calculate the TCP checksum for an outgoing packet. */
usGenerateProtocolChecksum( (uint8_t*)pxTCPPacket, pdTRUE );
usGenerateProtocolChecksum( (uint8_t*)pxTCPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
/* A calculated checksum of 0 must be inverted as 0 means the checksum
is disabled. */
@ -914,11 +896,9 @@ NetworkBufferDescriptor_t xTempBuffer;
}
#endif
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
pxNetworkBuffer->pxNextBuffer = NULL;
}
#endif
#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
pxNetworkBuffer->pxNextBuffer = NULL;
#endif
/* Important: tell NIC driver how many bytes must be sent. */
pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
@ -928,7 +908,7 @@ NetworkBufferDescriptor_t xTempBuffer;
sizeof( pxEthernetHeader->xDestinationAddress ) );
/* The source MAC addresses is fixed to 'ipLOCAL_MAC_ADDRESS'. */
memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress ), ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress) , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
{
@ -1002,6 +982,7 @@ eARPLookupResult_t eReturned;
uint32_t ulRemoteIP;
MACAddress_t xEthAddress;
BaseType_t xReturn = pdTRUE;
uint32_t ulInitialSequenceNumber = 0;
#if( ipconfigHAS_PRINTF != 0 )
{
@ -1017,32 +998,47 @@ BaseType_t xReturn = pdTRUE;
switch( eReturned )
{
case eARPCacheHit: /* An ARP table lookup found a valid entry. */
break; /* We can now prepare the SYN packet. */
case eARPCacheMiss: /* An ARP table lookup did not find a valid entry. */
case eCantSendPacket: /* There is no IP address, or an ARP is still in progress. */
default:
/* Count the number of times it couldn't find the ARP address. */
pxSocket->u.xTCP.ucRepCount++;
case eARPCacheHit: /* An ARP table lookup found a valid entry. */
break; /* We can now prepare the SYN packet. */
case eARPCacheMiss: /* An ARP table lookup did not find a valid entry. */
case eCantSendPacket: /* There is no IP address, or an ARP is still in progress. */
default:
/* Count the number of times it couldn't find the ARP address. */
pxSocket->u.xTCP.ucRepCount++;
FreeRTOS_debug_printf( ( "ARP for %lxip (using %lxip): rc=%d %02X:%02X:%02X %02X:%02X:%02X\n",
pxSocket->u.xTCP.ulRemoteIP,
FreeRTOS_htonl( ulRemoteIP ),
eReturned,
xEthAddress.ucBytes[ 0 ],
xEthAddress.ucBytes[ 1 ],
xEthAddress.ucBytes[ 2 ],
xEthAddress.ucBytes[ 3 ],
xEthAddress.ucBytes[ 4 ],
xEthAddress.ucBytes[ 5 ] ) );
FreeRTOS_debug_printf( ( "ARP for %lxip (using %lxip): rc=%d %02X:%02X:%02X %02X:%02X:%02X\n",
pxSocket->u.xTCP.ulRemoteIP,
FreeRTOS_htonl( ulRemoteIP ),
eReturned,
xEthAddress.ucBytes[ 0 ],
xEthAddress.ucBytes[ 1 ],
xEthAddress.ucBytes[ 2 ],
xEthAddress.ucBytes[ 3 ],
xEthAddress.ucBytes[ 4 ],
xEthAddress.ucBytes[ 5 ] ) );
/* And issue a (new) ARP request */
FreeRTOS_OutputARPRequest( ulRemoteIP );
/* And issue a (new) ARP request */
FreeRTOS_OutputARPRequest( ulRemoteIP );
xReturn = pdFALSE;
break;
xReturn = pdFALSE;
}
if( xReturn != pdFALSE )
{
/* Get a difficult-to-predict initial sequence number for this 4-tuple. */
ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber(
*ipLOCAL_IP_ADDRESS_POINTER,
pxSocket->usLocalPort,
pxSocket->u.xTCP.ulRemoteIP,
pxSocket->u.xTCP.usRemotePort );
/* Check for a random number generation error. */
if( 0 == ulInitialSequenceNumber )
{
xReturn = pdFALSE;
}
}
if( xReturn != pdFALSE )
{
/* The MAC-address of the peer (or gateway) has been found,
@ -1050,10 +1046,10 @@ BaseType_t xReturn = pdTRUE;
pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
pxIPHeader = &pxTCPPacket->xIPHeader;
/* Reset the retry counter to zero... */
/* reset the retry counter to zero. */
pxSocket->u.xTCP.ucRepCount = 0u;
/* ...and remember that the connect/SYN data are prepared. */
/* And remember that the connect/SYN data are prepared. */
pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE_UNSIGNED;
/* Now that the Ethernet address is known, the initial packet can be
@ -1086,11 +1082,7 @@ BaseType_t xReturn = pdTRUE;
pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 0ul;
/* Start with ISN (Initial Sequence Number). */
pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulNextInitialSequenceNumber;
/* And increment it with 268 for the next new connection, which is
recommended value. */
ulNextInitialSequenceNumber += 0x102UL;
pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
/* The TCP header size is 20 bytes, divided by 4 equals 5, which is put in
the high nibble of the TCP offset field. */
@ -1160,38 +1152,73 @@ UBaseType_t uxNewMSS;
pucLast = pucPtr + (((pxTCPHeader->ucTCPOffset >> 4) - 5) << 2);
pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
/* Validate options size calculation. */
if( pucLast > ( pxNetworkBuffer->pucEthernetBuffer + pxNetworkBuffer->xDataLength ) )
{
return;
}
/* The comparison with pucLast is only necessary in case the option data are
corrupted, we don't like to run into invalid memory and crash. */
while( pucPtr < pucLast )
{
UBaseType_t xRemainingOptionsBytes = pucLast - pucPtr;
if( pucPtr[ 0 ] == TCP_OPT_END )
{
/* End of options. */
return;
break;
}
if( pucPtr[ 0 ] == TCP_OPT_NOOP)
{
pucPtr++;
/* NOP option, inserted to make the length a multiple of 4. */
/* NOP option, inserted to make the length a multiple of 4. */
pucPtr++;
continue;
}
/* Any other well-formed option must be at least two bytes: the option
type byte followed by a length byte. */
if( xRemainingOptionsBytes < 2 )
{
break;
}
#if( ipconfigUSE_TCP_WIN != 0 )
else if( ( pucPtr[ 0 ] == TCP_OPT_WSOPT ) && ( pucPtr[ 1 ] == TCP_OPT_WSOPT_LEN ) )
else if( pucPtr[ 0 ] == TCP_OPT_WSOPT )
{
/* Confirm that the option fits in the remaining buffer space. */
if( xRemainingOptionsBytes < TCP_OPT_WSOPT_LEN ||
pucPtr[ 1 ] != TCP_OPT_WSOPT_LEN )
{
break;
}
pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ];
pxSocket->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
pucPtr += TCP_OPT_WSOPT_LEN;
}
#endif /* ipconfigUSE_TCP_WIN */
else if( ( pucPtr[ 0 ] == TCP_OPT_MSS ) && ( pucPtr[ 1 ] == TCP_OPT_MSS_LEN ) )
else if( pucPtr[ 0 ] == TCP_OPT_MSS )
{
/* An MSS option with the correct option length. FreeRTOS_htons()
/* Confirm that the option fits in the remaining buffer space. */
if( xRemainingOptionsBytes < TCP_OPT_MSS_LEN ||
pucPtr[ 1 ] != TCP_OPT_MSS_LEN )
{
break;
}
/* An MSS option with the correct option length. FreeRTOS_htons()
is not needed here because usChar2u16() already returns a host
endian number. */
uxNewMSS = usChar2u16( pucPtr + 2 );
if( pxSocket->u.xTCP.usInitMSS != uxNewMSS )
{
/* Perform a basic check on the the new MSS. */
if( uxNewMSS == 0 )
{
break;
}
FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", pxSocket->u.xTCP.usInitMSS, uxNewMSS ) );
}
@ -1225,11 +1252,11 @@ UBaseType_t uxNewMSS;
{
/* All other options have a length field, so that we easily
can skip past them. */
int len = ( int )pucPtr[ 1 ];
if( len == 0 )
unsigned char len = pucPtr[ 1 ];
if( len < 2 || len > xRemainingOptionsBytes )
{
/* If the length field is zero, the options are malformed
and we don't process them further. */
/* If the length field is too small or too big, the options are malformed.
Don't process them further. */
break;
}
@ -1284,16 +1311,6 @@ UBaseType_t uxNewMSS;
}
/* len should be 0 by now. */
}
#if ipconfigUSE_TCP_TIMESTAMPS == 1
else if( pucPtr[0] == TCP_OPT_TIMESTAMP )
{
len -= 2; /* Skip option and length byte. */
pucPtr += 2;
pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps = pdTRUE_UNSIGNED;
pxSocket->u.xTCP.xTCPWindow.rx.ulTimeStamp = ulChar2u32( pucPtr );
pxSocket->u.xTCP.xTCPWindow.tx.ulTimeStamp = ulChar2u32( pucPtr + 4 );
}
#endif /* ipconfigUSE_TCP_TIMESTAMPS == 1 */
}
#endif /* ipconfigUSE_TCP_WIN == 1 */
@ -1371,24 +1388,13 @@ UBaseType_t uxOptionsLength;
}
#else
{
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps )
{
uxOptionsLength += prvTCPSetTimeStamp( uxOptionsLength, pxSocket, &pxTCPPacket->xTCPHeader );
pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = 2u;
uxOptionsLength += 2u;
}
else
#endif
{
pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_NOOP;
pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = TCP_OPT_NOOP;
pxTCPHeader->ucOptdata[ uxOptionsLength + 2 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
pxTCPHeader->ucOptdata[ uxOptionsLength + 3 ] = 2; /* 2: length of this option. */
uxOptionsLength += 4u;
}
return uxOptionsLength; /* bytes, not words. */
pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_NOOP;
pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = TCP_OPT_NOOP;
pxTCPHeader->ucOptdata[ uxOptionsLength + 2 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
pxTCPHeader->ucOptdata[ uxOptionsLength + 3 ] = 2; /* 2: length of this option. */
uxOptionsLength += 4u;
return uxOptionsLength; /* bytes, not words. */
}
#endif /* ipconfigUSE_TCP_WIN == 0 */
}
@ -1566,7 +1572,7 @@ BaseType_t bAfter = ( BaseType_t ) NOW_CONNECTED( eTCPState ); /* Is it co
/* Fill in the new state. */
pxSocket->u.xTCP.ucTCPState = ( uint8_t ) eTCPState;
/* Touch the alive timers because moving to another state. */
/* touch the alive timers because moving to another state. */
prvTCPTouchSocket( pxSocket );
#if( ipconfigHAS_DEBUG_PRINTF == 1 )
@ -1621,14 +1627,7 @@ BaseType_t xResize;
( int32_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen );
/* In case we were called from a TCP timer event, a buffer must be
created. Otherwise, test 'xDataLength' of the provided buffer. */
if( ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded ) )
{
xResize = pdTRUE;
}
else
{
xResize = pdFALSE;
}
xResize = ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded );
}
if( xResize != pdFALSE )
@ -1640,6 +1639,9 @@ BaseType_t xResize;
if( pxReturn != NULL )
{
/* Set the actual packet size, in case the returned buffer is larger. */
pxReturn->xDataLength = lNeeded;
/* Copy the existing data to the new created buffer. */
if( pxNetworkBuffer )
{
@ -1695,8 +1697,8 @@ int32_t lStreamPos;
pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
}
pxTCPPacket = ( TCPPacket_t * ) pucEthernetBuffer;
pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
lDataLen = 0;
lStreamPos = 0;
pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_ACK;
@ -1848,19 +1850,6 @@ int32_t lStreamPos;
pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_PSH;
}
#if ipconfigUSE_TCP_TIMESTAMPS == 1
{
if( uxOptionsLength == 0u )
{
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps )
{
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
uxOptionsLength = prvTCPSetTimeStamp( 0, pxSocket, &pxTCPPacket->xTCPHeader );
}
}
}
#endif
lDataLen += ( int32_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
}
@ -1941,9 +1930,9 @@ 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. */
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. */
lLength = ( int32_t ) uxStreamBufferMidSpace( pxSocket->u.xTCP.txStream );
if( lLength > 0 )
@ -2064,29 +2053,6 @@ uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr );
}
/*-----------------------------------------------------------*/
#if ipconfigUSE_TCP_TIMESTAMPS == 1
static UBaseType_t prvTCPSetTimeStamp( BaseType_t lOffset, FreeRTOS_Socket_t *pxSocket, TCPHeader_t *pxTCPHeader )
{
uint32_t ulTimes[2];
uint8_t *ucOptdata = &( pxTCPHeader->ucOptdata[ lOffset ] );
ulTimes[0] = ( xTaskGetTickCount ( ) * 1000u ) / configTICK_RATE_HZ;
ulTimes[0] = FreeRTOS_htonl( ulTimes[0] );
ulTimes[1] = FreeRTOS_htonl( pxSocket->u.xTCP.xTCPWindow.rx.ulTimeStamp );
ucOptdata[0] = ( uint8_t ) TCP_OPT_TIMESTAMP;
ucOptdata[1] = ( uint8_t ) TCP_OPT_TIMESTAMP_LEN;
memcpy( &(ucOptdata[2] ), ulTimes, 8u );
ucOptdata[10] = ( uint8_t ) TCP_OPT_NOOP;
ucOptdata[11] = ( uint8_t ) TCP_OPT_NOOP;
/* Do not return the same timestamps 2 times. */
pxSocket->u.xTCP.xTCPWindow.rx.ulTimeStamp = 0ul;
return 12u;
}
#endif
/*-----------------------------------------------------------*/
/*
* prvCheckRxData(): called from prvTCPHandleState()
*
@ -2279,15 +2245,6 @@ UBaseType_t uxOptionsLength = pxTCPWindow->ucOptionLength;
pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
}
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
{
if( pxSocket->u.xTCP.xTCPWindow.u.bits.bTimeStamps )
{
uxOptionsLength += prvTCPSetTimeStamp( uxOptionsLength, pxSocket, pxTCPHeader );
}
}
#endif /* ipconfigUSE_TCP_TIMESTAMPS == 1 */
return uxOptionsLength;
}
/*-----------------------------------------------------------*/
@ -2941,16 +2898,31 @@ BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer
{
FreeRTOS_Socket_t *pxSocket;
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
uint16_t ucTCPFlags = pxTCPPacket->xTCPHeader.ucTCPFlags;
uint32_t ulLocalIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulDestinationIPAddress );
uint16_t xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
uint32_t ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
uint16_t xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
uint16_t ucTCPFlags;
uint32_t ulLocalIP;
uint16_t xLocalPort;
uint32_t ulRemoteIP;
uint16_t xRemotePort;
BaseType_t xResult = pdPASS;
/* Find the destination socket, and if not found: return a socket listing to
the destination PORT. */
pxSocket = ( FreeRTOS_Socket_t * ) pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort );
/* Check for a minimum packet size. */
if( pxNetworkBuffer->xDataLength >=
ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER )
{
ucTCPFlags = pxTCPPacket->xTCPHeader.ucTCPFlags;
ulLocalIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulDestinationIPAddress );
xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
/* Find the destination socket, and if not found: return a socket listing to
the destination PORT. */
pxSocket = ( FreeRTOS_Socket_t * )pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort );
}
else
{
return pdFAIL;
}
if( ( pxSocket == NULL ) || ( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE ) )
{
@ -3111,59 +3083,71 @@ BaseType_t xResult = pdPASS;
static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
{
TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
FreeRTOS_Socket_t *pxReturn;
FreeRTOS_Socket_t *pxReturn = NULL;
uint32_t ulInitialSequenceNumber;
/* Assume that a new Initial Sequence Number will be required. Request
it now in order to fail out if necessary. */
ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber(
*ipLOCAL_IP_ADDRESS_POINTER,
pxSocket->usLocalPort,
pxTCPPacket->xIPHeader.ulSourceIPAddress,
pxTCPPacket->xTCPHeader.usSourcePort );
/* A pure SYN (without ACK) has come in, create a new socket to answer
it. */
if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
{
/* The flag bReuseSocket indicates that the same instance of the
listening socket should be used for the connection. */
pxReturn = pxSocket;
pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
pxSocket->u.xTCP.pxPeerSocket = pxSocket;
}
else
{
/* The socket does not have the bReuseSocket flag set meaning create a
new socket when a connection comes in. */
pxReturn = NULL;
if( 0 != ulInitialSequenceNumber )
{
if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
{
/* The flag bReuseSocket indicates that the same instance of the
listening socket should be used for the connection. */
pxReturn = pxSocket;
pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
pxSocket->u.xTCP.pxPeerSocket = pxSocket;
}
else
{
/* The socket does not have the bReuseSocket flag set meaning create a
new socket when a connection comes in. */
pxReturn = NULL;
if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog )
{
FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n",
pxSocket->usLocalPort,
pxSocket->u.xTCP.usChildCount,
pxSocket->u.xTCP.usBacklog,
pxSocket->u.xTCP.usChildCount == 1 ? "" : "ren" ) );
prvTCPSendReset( pxNetworkBuffer );
}
else
{
FreeRTOS_Socket_t *pxNewSocket = (FreeRTOS_Socket_t *)
FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog )
{
FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n",
pxSocket->usLocalPort,
pxSocket->u.xTCP.usChildCount,
pxSocket->u.xTCP.usBacklog,
pxSocket->u.xTCP.usChildCount == 1 ? "" : "ren" ) );
prvTCPSendReset( pxNetworkBuffer );
}
else
{
FreeRTOS_Socket_t *pxNewSocket = ( FreeRTOS_Socket_t * )
FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) )
{
FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) );
prvTCPSendReset( pxNetworkBuffer );
}
else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE )
{
/* The socket will be connected immediately, no time for the
owner to setsockopt's, therefore copy properties of the server
socket to the new socket. Only the binding might fail (due to
lack of resources). */
pxReturn = pxNewSocket;
}
}
}
if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) )
{
FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) );
prvTCPSendReset( pxNetworkBuffer );
}
else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE )
{
/* The socket will be connected immediately, no time for the
owner to setsockopt's, therefore copy properties of the server
socket to the new socket. Only the binding might fail (due to
lack of resources). */
pxReturn = pxNewSocket;
}
}
}
}
if( pxReturn != NULL )
if( 0 != ulInitialSequenceNumber && pxReturn != NULL )
{
pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
pxReturn->u.xTCP.ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulNextInitialSequenceNumber;
pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
/* Here is the SYN action. */
pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
@ -3171,9 +3155,6 @@ FreeRTOS_Socket_t *pxReturn;
prvTCPCreateWindow( pxReturn );
/* It is recommended to increase the ISS for each new connection with a value of 0x102. */
ulNextInitialSequenceNumber += INITIAL_SEQUENCE_NUMBER_INCREMENT;
vTCPStateChange( pxReturn, eSYN_FIRST );
/* Make a copy of the header up to the TCP header. It is needed later
@ -3248,7 +3229,7 @@ struct freertos_sockaddr xAddress;
/* A reference to the new socket may be stored and the socket is marked
as 'passable'. */
/* When bPassAccept is true, this socket may be returned in a call to
/* When bPassAccept is pdTRUE_UNSIGNED this socket may be returned in a call to
accept(). */
pxNewSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
if(pxSocket->u.xTCP.pxPeerSocket == NULL )
@ -3327,3 +3308,7 @@ BaseType_t xResult = pdFALSE;
#endif /* ipconfigUSE_TCP == 1 */
/* Provide access to private members for testing. */
#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
#include "aws_freertos_tcp_test_access_tcp_define.h"
#endif

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -199,7 +199,7 @@ extern void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewL
/*-----------------------------------------------------------*/
/* TCP segment pool. */
/* TCP segement pool. */
#if( ipconfigUSE_TCP_WIN == 1 )
static TCPSegment_t *xTCPSegments = NULL;
#endif /* ipconfigUSE_TCP_WIN == 1 */
@ -292,7 +292,7 @@ void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem
pxWhere->pxPrevious = pxNewListItem;
/* Remember which list the item is in. */
pxNewListItem->pxContainer = pxList;
pxNewListItem->pvContainer = ( void * ) pxList; /* If this line fails to build then ensure configENABLE_BACKWARD_COMPATIBILITY is set to 1 in FreeRTOSConfig.h. */
( pxList->uxNumberOfItems )++;
}
@ -597,12 +597,12 @@ void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
prvCreateSectors();
}
vListInitialise( &( pxWindow->xTxSegments ) );
vListInitialise( &( pxWindow->xRxSegments ) );
vListInitialise( &pxWindow->xTxSegments );
vListInitialise( &pxWindow->xRxSegments );
vListInitialise( &( pxWindow->xPriorityQueue ) ); /* Priority queue: segments which must be sent immediately */
vListInitialise( &( pxWindow->xTxQueue ) ); /* Transmit queue: segments queued for transmission */
vListInitialise( &( pxWindow->xWaitQueue ) ); /* Waiting queue: outstanding segments */
vListInitialise( &pxWindow->xPriorityQueue ); /* Priority queue: segments which must be sent immediately */
vListInitialise( &pxWindow->xTxQueue ); /* Transmit queue: segments queued for transmission */
vListInitialise( &pxWindow->xWaitQueue ); /* Waiting queue: outstanding segments */
}
#endif /* ipconfigUSE_TCP_WIN == 1 */
@ -788,23 +788,20 @@ const int32_t l500ms = 500;
{
ulSavedSequenceNumber = ulCurrentSequenceNumber;
/* Clean up all sequence received between ulSequenceNumber
and ulSequenceNumber + ulLength since they are duplicated.
If the server is forced to retransmit packets several time
in a row it might send a batch of concatenated packet for
speed. So we cannot rely on the packets between
ulSequenceNumber and ulSequenceNumber + ulLength to be
sequential and it is better to just clean them out. */
do
{
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
/* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
clean them out. */
do
{
pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
if ( pxFound != NULL )
{
/* Remove it because it will be passed to user directly. */
vTCPWindowFree( pxFound );
}
} while ( pxFound );
if ( pxFound != NULL )
{
/* Remove it because it will be passed to user directly. */
vTCPWindowFree( pxFound );
}
} while ( pxFound );
/* Check for following segments that are already in the
queue and increment ulCurrentSequenceNumber. */

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -128,15 +128,16 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
and
xIPHeader.usHeaderChecksum
*/
/* Save options now, as they will be overwritten by memcpy */
#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
{
ucSocketOptions = pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ];
}
#endif
memcpy( ( void *) &( pxUDPPacket->xEthernetHeader.xSourceAddress ), ( void * ) xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );
/*
* Offset the memcpy by the size of a MAC address to start at the packet's
* Ethernet header 'source' MAC address; the preceding 'destination' should not be altered.
*/
char *pxUdpSrcAddrOffset = ( char *) pxUDPPacket + sizeof( MACAddress_t );
memcpy( pxUdpSrcAddrOffset, xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );
#if ipconfigSUPPORT_OUTGOING_PINGS == 1
if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
@ -153,6 +154,7 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
/* The total transmit size adds on the Ethernet header. */
pxNetworkBuffer->xDataLength = pxIPHeader->usLength + sizeof( EthernetHeader_t );
pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
/* HT:endian: changed back to network endian */
pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;
#if( ipconfigUSE_LLMNR == 1 )
@ -174,7 +176,7 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
if( ( ucSocketOptions & ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT ) != 0u )
{
usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pdTRUE );
usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
}
else
{
@ -241,7 +243,8 @@ FreeRTOS_Socket_t *pxSocket;
UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
pxSocket = pxUDPSocketLookup( usPort );
/* Caller must check for minimum packet size. */
pxSocket = pxUDPSocketLookup( usPort );
if( pxSocket )
{
@ -265,9 +268,9 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
if( xHandler( ( Socket_t * ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
&xSourceAddress, &destinationAddress ) != pdFALSE )
&xSourceAddress, &destinationAddress ) )
{
xReturn = pdFAIL; /* xHandler has consumed the data, do not add it to .xWaitingPacketsList'. */
xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
}
}
}
@ -344,21 +347,8 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
/* There is no socket listening to the target port, but still it might
be for this node. */
#if( ipconfigUSE_DNS == 1 )
/* A DNS reply, check for the source port. Although the DNS client
does open a UDP socket to send a messages, this socket will be
closed after a short timeout. Messages that come late (after the
socket is closed) will be treated here. */
if( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usSourcePort ) == ipDNS_PORT )
{
vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
}
else
#endif
#if( ipconfigUSE_LLMNR == 1 )
/* An LLMNR request, check for the destination port. */
/* a LLMNR request, check for the destination port. */
if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||
( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) )
{

View File

@ -1,4 +1,11 @@
Changes since V2.0.0 release
Changes between 160919 and 180821 releases:
+ Multiple security improvements and fixes in packet parsing routines, DNS
caching, and TCP sequence number and ID generation.
+ Disable NBNS and LLMNR by default.
+ Add TCP hang protection by default.
We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
+ Update FreeRTOS_gethostbyname() to allow an IP address to be passed in -
in which case it is just returned as a uint32_t.

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -389,11 +389,13 @@ from the FreeRTOSIPConfig.h configuration header file. */
#if( ipconfigUSE_DNS_CACHE != 0 )
#ifndef ipconfigDNS_CACHE_NAME_LENGTH
#define ipconfigDNS_CACHE_NAME_LENGTH ( 16 )
/* Per https://tools.ietf.org/html/rfc1035, 253 is the maximum string length
of a DNS name. The following default accounts for a null terminator. */
#define ipconfigDNS_CACHE_NAME_LENGTH 254
#endif
#ifndef ipconfigDNS_CACHE_ENTRIES
#define ipconfigDNS_CACHE_ENTRIES 0
#define ipconfigDNS_CACHE_ENTRIES 1
#endif
#endif /* ipconfigUSE_DNS_CACHE != 0 */
@ -510,7 +512,7 @@ from the FreeRTOSIPConfig.h configuration header file. */
#endif
#ifndef ipconfigTCP_KEEP_ALIVE
#define ipconfigTCP_KEEP_ALIVE 1
#define ipconfigTCP_KEEP_ALIVE 0
#endif
#ifndef ipconfigDNS_USE_CALLBACKS
@ -525,10 +527,17 @@ from the FreeRTOSIPConfig.h configuration header file. */
#define ipconfigUSE_NBNS 0
#endif
/* As an attack surface reduction for ports that listen for inbound
connections, hang protection can help reduce the impact of SYN floods. */
#ifndef ipconfigTCP_HANG_PROTECTION
#define ipconfigTCP_HANG_PROTECTION 1
#endif
/* Non-activity timeout is expressed in seconds. */
#ifndef ipconfigTCP_HANG_PROTECTION_TIME
#define ipconfigTCP_HANG_PROTECTION_TIME 30
#endif
#ifndef ipconfigTCP_IP_SANITY
#define ipconfigTCP_IP_SANITY 0
#endif

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -436,8 +436,18 @@ eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucE
uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes );
/* Socket related private functions. */
/*
* The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
* payload size (excluding packet headers) and that the packet in pucEthernetBuffer
* is at least the size of UDPPacket_t.
*/
BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort );
void vNetworkSocketsInit( void );
/*
* Initialize the socket list data structures for TCP and UDP.
*/
BaseType_t vNetworkSocketsInit( void );
/*
* Returns pdTRUE if the IP task has been created and is initialised. Otherwise
@ -671,7 +681,7 @@ void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuff
* bOut = false: checksum will be calculated for incoming packets
* returning 0xffff means: checksum was correct
*/
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, BaseType_t xOutgoingPacket );
uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket );
/*
* An Ethernet frame has been updated (maybe it was an ARP request or a PING

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -80,17 +80,9 @@ typedef struct xTCP_WINSIZE
*/
/* Keep this as a multiple of 4 */
#if( ipconfigUSE_TCP_WIN == 1 )
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
#define ipSIZE_TCP_OPTIONS ( 16u + 12u )
#else
#define ipSIZE_TCP_OPTIONS 16u
#endif
#define ipSIZE_TCP_OPTIONS 16u
#else
#if ipconfigUSE_TCP_TIMESTAMPS == 1
#define ipSIZE_TCP_OPTIONS ( 12u + 12u )
#else
#define ipSIZE_TCP_OPTIONS 12u
#endif
#define ipSIZE_TCP_OPTIONS 12u
#endif
/*
@ -120,9 +112,6 @@ typedef struct xTCP_WINDOW
* In other words: the sequence number of the left side of the sliding window */
uint32_t ulFINSequenceNumber; /* The sequence number which carried the FIN flag */
uint32_t ulHighestSequenceNumber;/* Sequence number of the right-most byte + 1 */
#if( ipconfigUSE_TCP_TIMESTAMPS == 1 )
uint32_t ulTimeStamp; /* The value of the TCP timestamp, transmitted or received */
#endif
} rx, tx;
uint32_t ulOurSequenceNumber; /* The SEQ number we're sending out */
uint32_t ulUserDataLength; /* Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/******************************************************************************
*
@ -226,7 +225,7 @@ UBaseType_t uxCount;
available. */
if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
{
/* Protect the structure as it is accessed from tasks and
/* Protect the structure as they are accessed from tasks and
interrupts. */
ipconfigBUFFER_ALLOC_LOCK();
{

View File

@ -1,5 +1,5 @@
/*
* FreeRTOS+TCP V2.0.3
* FreeRTOS+TCP V2.0.7
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
@ -19,11 +19,12 @@
* 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
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/******************************************************************************
*
* See the following web page for essential buffer allocation scheme usage and
@ -323,12 +324,21 @@ BaseType_t xListItemAlreadyInFreeList;
}
taskEXIT_CRITICAL();
/*
* Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
* The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
*/
if( xListItemAlreadyInFreeList == pdFALSE )
{
xSemaphoreGive( xNetworkBufferSemaphore );
if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
{
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
}
else
{
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
}
/*-----------------------------------------------------------*/

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/*****************************************************************************
*

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/* Standard includes. */
#include <stdint.h>

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/* Standard includes. */
#include <stdint.h>

View File

@ -787,16 +787,11 @@ uint8_t *pucBuffer;
}
/* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
/* get received frame */
if( xReceivedLength > 0ul )
/* In order to make the code easier and faster, only packets in a single buffer
will be accepted. This can be done by making the buffers large enough to
hold a complete Ethernet packet (1536 bytes). */
if( xReceivedLength > 0ul && xReceivedLength < ETH_RX_BUF_SIZE )
{
/* In order to make the code easier and faster, only packets in a single buffer
will be accepted. This can be done by making the buffers large enough to
hold a complete Ethernet packet (1536 bytes).
Therefore, two sanity checks: */
configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
{
/* Not an Ethernet frame-type or a checmsum error. */

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/* WinPCap includes. */
#define HAVE_REMOTE
@ -80,7 +79,7 @@ static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
* by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
*/
static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
static void prvOpenInterface( const char *pucName );
static int prvOpenInterface( const char *pucName );
/*
* Configure the capture filter to allow blocking reads, and to filter out
@ -275,7 +274,7 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
printf( "\r\nThe interface that will be opened is set by " );
printf( "\"configNETWORK_INTERFACE_TO_USE\", which\r\nshould be defined in FreeRTOSConfig.h\r\n" );
if( ( xConfigNextworkInterfaceToUse < 1L ) || ( xConfigNextworkInterfaceToUse >= lInterfaceNumber ) )
if( ( xConfigNextworkInterfaceToUse < 0L ) || ( xConfigNextworkInterfaceToUse >= lInterfaceNumber ) )
{
printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNextworkInterfaceToUse );
printf( "Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above,\r\n" );
@ -300,7 +299,7 @@ static BaseType_t xInvalidInterfaceDetected = pdFALSE;
}
/*-----------------------------------------------------------*/
static void prvOpenInterface( const char *pucName )
static int prvOpenInterface( const char *pucName )
{
static char pucInterfaceName[ 256 ];
@ -326,6 +325,7 @@ static char pucInterfaceName[ 256 ];
if ( pxOpenedInterfaceHandle == NULL )
{
printf( "\n%s is not supported by WinPcap and cannot be opened\n", pucInterfaceName );
return 1;
}
else
{
@ -333,6 +333,7 @@ static char pucInterfaceName[ 256 ];
out packets that are not of interest to this demo. */
prvConfigureCaptureBehaviour();
}
return 0;
}
/*-----------------------------------------------------------*/
@ -343,13 +344,22 @@ int32_t x;
/* Walk the list of devices until the selected device is located. */
xInterface = pxAllNetworkInterfaces;
for( x = 0L; x < ( xConfigNextworkInterfaceToUse - 1L ); x++ )
{
xInterface = xInterface->next;
if (0 == xConfigNextworkInterfaceToUse) {
while (NULL != xInterface) {
xInterface = xInterface->next;
if (0 == prvOpenInterface(xInterface->name)) {
break;
}
}
}
else {
for (x = 1L; x < xConfigNextworkInterfaceToUse; x++)
{
xInterface = xInterface->next;
}
/* Open the selected interface. */
(void) prvOpenInterface(xInterface->name);
}
/* Open the selected interface. */
prvOpenInterface( xInterface->name );
/* The device list is no longer required. */
pcap_freealldevs( pxAllNetworkInterfaces );
@ -514,7 +524,16 @@ eFrameProcessingResult_t eResult;
iptraceNETWORK_INTERFACE_RECEIVE();
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
/* Check for minimal size. */
if( pxHeader->len >= sizeof( EthernetHeader_t ) )
{
eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
}
else
{
eResult = eReleaseBuffer;
}
if( eResult == eProcessBuffer )
{
/* Will the data fit into the frame buffer? */

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/* Standard includes. */
#include <stdint.h>

View File

@ -1,27 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
#include "Zynq/x_emacpsif.h"
#include "Zynq/x_topology.h"

View File

@ -1,28 +1,27 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
FreeRTOS+TCP V2.0.7
Copyright (C) 2017 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
*/
/* Standard includes. */
#include <stdint.h>

View File

@ -1,353 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_TCP_server.h"
#include "FreeRTOS_server_private.h"
/* Remove the entire file if TCP is not being used. */
#if( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) )
#if !defined( ARRAY_SIZE )
#define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] )
#endif
static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket );
static char *strnew( const char *pcString );
/* Remove slashes at the end of a path. */
static void prvRemoveSlash( char *pcDir );
TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount )
{
TCPServer_t *pxServer;
SocketSet_t xSocketSet;
/* Create a new server.
xPort / xPortAlt : Make the service available on 1 or 2 public port numbers. */
xSocketSet = FreeRTOS_CreateSocketSet();
if( xSocketSet != NULL )
{
BaseType_t xSize;
xSize = sizeof( *pxServer ) - sizeof( pxServer->xServers ) + xCount * sizeof( pxServer->xServers[ 0 ] );
pxServer = ( TCPServer_t * ) pvPortMallocLarge( xSize );
if( pxServer != NULL )
{
struct freertos_sockaddr xAddress;
BaseType_t xNoTimeout = 0;
BaseType_t xIndex;
memset( pxServer, '\0', xSize );
pxServer->xServerCount = xCount;
pxServer->xSocketSet = xSocketSet;
for( xIndex = 0; xIndex < xCount; xIndex++ )
{
BaseType_t xPortNumber = pxConfigs[ xIndex ].xPortNumber;
if( xPortNumber > 0 )
{
Socket_t xSocket;
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
FreeRTOS_printf( ( "TCP socket on port %d\n", ( int )xPortNumber ) );
if( xSocket != FREERTOS_NO_SOCKET )
{
xAddress.sin_addr = FreeRTOS_GetIPAddress(); // Single NIC, currently not used
xAddress.sin_port = FreeRTOS_htons( xPortNumber );
FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
FreeRTOS_listen( xSocket, pxConfigs[ xIndex ].xBackLog );
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xNoTimeout, sizeof( BaseType_t ) );
#if( ipconfigHTTP_RX_BUFSIZE > 0 )
{
if( pxConfigs[ xIndex ].eType == eSERVER_HTTP )
{
WinProperties_t xWinProps;
memset( &xWinProps, '\0', sizeof( xWinProps ) );
/* The parent socket itself won't get connected. The properties below
will be inherited by each new child socket. */
xWinProps.lTxBufSize = ipconfigHTTP_TX_BUFSIZE;
xWinProps.lTxWinSize = ipconfigHTTP_TX_WINSIZE;
xWinProps.lRxBufSize = ipconfigHTTP_RX_BUFSIZE;
xWinProps.lRxWinSize = ipconfigHTTP_RX_WINSIZE;
/* Set the window and buffer sizes. */
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
}
}
#endif
FreeRTOS_FD_SET( xSocket, xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
pxServer->xServers[ xIndex ].xSocket = xSocket;
pxServer->xServers[ xIndex ].eType = pxConfigs[ xIndex ].eType;
pxServer->xServers[ xIndex ].pcRootDir = strnew( pxConfigs[ xIndex ].pcRootDir );
prvRemoveSlash( ( char * ) pxServer->xServers[ xIndex ].pcRootDir );
}
}
}
}
else
{
/* Could not allocate the server, delete the socket set */
FreeRTOS_DeleteSocketSet( xSocketSet );
}
}
else
{
/* Could not create a socket set, return NULL */
pxServer = NULL;
}
return pxServer;
}
/*-----------------------------------------------------------*/
static void prvReceiveNewClient( TCPServer_t *pxServer, BaseType_t xIndex, Socket_t xNexSocket )
{
TCPClient_t *pxClient = NULL;
BaseType_t xSize = 0;
FTCPWorkFunction fWorkFunc = NULL;
FTCPDeleteFunction fDeleteFunc = NULL;
const char *pcType = "Unknown";
/*_RB_ Can the work and delete functions be part of the xSERVER_CONFIG structure
becomes generic, with no pre-processing required? */
#if( ipconfigUSE_HTTP != 0 )
{
if( pxServer->xServers[ xIndex ].eType == eSERVER_HTTP )
{
xSize = sizeof( HTTPClient_t );
fWorkFunc = xHTTPClientWork;
fDeleteFunc = vHTTPClientDelete;
pcType = "HTTP";
}
}
#endif /* ipconfigUSE_HTTP != 0 */
#if( ipconfigUSE_FTP != 0 )
{
if( pxServer->xServers[ xIndex ].eType == eSERVER_FTP )
{
xSize = sizeof( FTPClient_t );
fWorkFunc = xFTPClientWork;
fDeleteFunc = vFTPClientDelete;
pcType = "FTP";
}
}
#endif /* ipconfigUSE_FTP != 0 */
/* Malloc enough space for a new HTTP-client */
if( xSize )
{
pxClient = ( TCPClient_t* ) pvPortMallocLarge( xSize );
}
if( pxClient != NULL )
{
memset( pxClient, '\0', xSize );
/* Put the new client in front of the list. */
pxClient->eType = pxServer->xServers[ xIndex ].eType;
pxClient->pcRootDir = pxServer->xServers[ xIndex ].pcRootDir;
pxClient->pxParent = pxServer;
pxClient->xSocket = xNexSocket;
pxClient->pxNextClient = pxServer->pxClients;
pxClient->fWorkFunction = fWorkFunc;
pxClient->fDeleteFunction = fDeleteFunc;
pxServer->pxClients = pxClient;
FreeRTOS_FD_SET( xNexSocket, pxServer->xSocketSet, eSELECT_READ|eSELECT_EXCEPT );
}
else
{
pcType = "closed";
FreeRTOS_closesocket( xNexSocket );
}
{
struct freertos_sockaddr xRemoteAddress;
FreeRTOS_GetRemoteAddress( pxClient->xSocket, &xRemoteAddress );
FreeRTOS_printf( ( "TPC-server: new %s client %xip\n", pcType, (unsigned)FreeRTOS_ntohl( xRemoteAddress.sin_addr ) ) );
}
/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
( void ) pcType;
}
/*-----------------------------------------------------------*/
void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime )
{
TCPClient_t **ppxClient;
BaseType_t xIndex;
BaseType_t xRc;
/* Let the server do one working cycle */
xRc = FreeRTOS_select( pxServer->xSocketSet, xBlockingTime );
if( xRc != 0 )
{
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
{
struct freertos_sockaddr xAddress;
Socket_t xNexSocket;
socklen_t xSocketLength;
if( pxServer->xServers[ xIndex ].xSocket == FREERTOS_NO_SOCKET )
{
continue;
}
xSocketLength = sizeof( xAddress );
xNexSocket = FreeRTOS_accept( pxServer->xServers[ xIndex ].xSocket, &xAddress, &xSocketLength);
if( ( xNexSocket != FREERTOS_NO_SOCKET ) && ( xNexSocket != FREERTOS_INVALID_SOCKET ) )
{
prvReceiveNewClient( pxServer, xIndex, xNexSocket );
}
}
}
ppxClient = &pxServer->pxClients;
while( ( * ppxClient ) != NULL )
{
TCPClient_t *pxThis = *ppxClient;
/* Almost C++ */
xRc = pxThis->fWorkFunction( pxThis );
if (xRc < 0 )
{
*ppxClient = pxThis->pxNextClient;
/* Close handles, resources */
pxThis->fDeleteFunction( pxThis );
/* Free the space */
vPortFreeLarge( pxThis );
}
else
{
ppxClient = &( pxThis->pxNextClient );
}
}
}
/*-----------------------------------------------------------*/
static char *strnew( const char *pcString )
{
BaseType_t xLength;
char *pxBuffer;
xLength = strlen( pcString ) + 1;
pxBuffer = ( char * ) pvPortMalloc( xLength );
if( pxBuffer != NULL )
{
memcpy( pxBuffer, pcString, xLength );
}
return pxBuffer;
}
/*-----------------------------------------------------------*/
static void prvRemoveSlash( char *pcDir )
{
BaseType_t xLength = strlen( pcDir );
while( ( xLength > 0 ) && ( pcDir[ xLength - 1 ] == '/' ) )
{
pcDir[ --xLength ] = '\0';
}
}
/*-----------------------------------------------------------*/
#if( ipconfigSUPPORT_SIGNALS != 0 )
/* FreeRTOS_TCPServerWork() calls select().
The two functions below provide a possibility to interrupt
the call to select(). After the interruption, resume
by calling FreeRTOS_TCPServerWork() again. */
BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer )
{
BaseType_t xIndex;
BaseType_t xResult = pdFALSE;
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
{
if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
{
FreeRTOS_SignalSocket( pxServer->xServers[ xIndex ].xSocket );
xResult = pdTRUE;
break;
}
}
return xResult;
}
#endif /* ipconfigSUPPORT_SIGNALS */
/*-----------------------------------------------------------*/
#if( ipconfigSUPPORT_SIGNALS != 0 )
/* Same as above: this function may be called from an ISR,
for instance a GPIO interrupt. */
BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken )
{
BaseType_t xIndex;
BaseType_t xResult = pdFALSE;
for( xIndex = 0; xIndex < pxServer->xServerCount; xIndex++ )
{
if( pxServer->xServers[ xIndex ].xSocket != FREERTOS_NO_SOCKET )
{
FreeRTOS_SignalSocketFromISR( pxServer->xServers[ xIndex ].xSocket, pxHigherPriorityTaskWoken );
xResult = pdTRUE;
break;
}
}
return xResult;
}
#endif /* ipconfigSUPPORT_SIGNALS */
/*-----------------------------------------------------------*/
#endif /* ( ipconfigUSE_TCP == 1 ) && ( ( ipconfigUSE_HTTP == 1 ) || ( ipconfigUSE_FTP == 1 ) ) */

View File

@ -1,74 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
/* FreeRTOS includes. */
#include "FreeRTOS.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_FTP_commands.h"
const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ] =
{
/* cmdLen cmdName[7] cmdType checkLogin checkNullArg */
{ 4, "USER", ECMD_USER, pdFALSE, pdFALSE },
{ 4, "PASS", ECMD_PASS, pdFALSE, pdFALSE },
{ 4, "ACCT", ECMD_ACCT, pdTRUE, pdFALSE },
{ 3, "CWD", ECMD_CWD, pdTRUE, pdTRUE },
{ 4, "CDUP", ECMD_CDUP, pdTRUE, pdFALSE },
{ 4, "SMNT", ECMD_SMNT, pdTRUE, pdFALSE },
{ 4, "QUIT", ECMD_QUIT, pdTRUE, pdFALSE },
{ 4, "REIN", ECMD_REIN, pdTRUE, pdFALSE },
{ 4, "PORT", ECMD_PORT, pdTRUE, pdFALSE },
{ 4, "PASV", ECMD_PASV, pdTRUE, pdFALSE },
{ 4, "TYPE", ECMD_TYPE, pdTRUE, pdFALSE },
{ 4, "STRU", ECMD_STRU, pdTRUE, pdFALSE },
{ 4, "MODE", ECMD_MODE, pdTRUE, pdFALSE },
{ 4, "RETR", ECMD_RETR, pdTRUE, pdTRUE },
{ 4, "STOR", ECMD_STOR, pdTRUE, pdTRUE },
{ 4, "STOU", ECMD_STOU, pdTRUE, pdFALSE },
{ 4, "APPE", ECMD_APPE, pdTRUE, pdFALSE },
{ 4, "ALLO", ECMD_ALLO, pdTRUE, pdFALSE },
{ 4, "REST", ECMD_REST, pdTRUE, pdFALSE },
{ 4, "RNFR", ECMD_RNFR, pdTRUE, pdTRUE },
{ 4, "RNTO", ECMD_RNTO, pdTRUE, pdTRUE },
{ 4, "ABOR", ECMD_ABOR, pdTRUE, pdFALSE },
{ 4, "SIZE", ECMD_SIZE, pdTRUE, pdTRUE },
{ 4, "MDTM", ECMD_MDTM, pdTRUE, pdTRUE },
{ 4, "DELE", ECMD_DELE, pdTRUE, pdTRUE },
{ 3, "RMD", ECMD_RMD, pdTRUE, pdTRUE },
{ 3, "MKD", ECMD_MKD, pdTRUE, pdTRUE },
{ 3, "PWD", ECMD_PWD, pdTRUE, pdFALSE },
{ 4, "LIST", ECMD_LIST, pdTRUE, pdFALSE },
{ 4, "NLST", ECMD_NLST, pdTRUE, pdFALSE },
{ 4, "SITE", ECMD_SITE, pdTRUE, pdFALSE },
{ 4, "SYST", ECMD_SYST, pdFALSE, pdFALSE },
{ 4, "FEAT", ECMD_FEAT, pdFALSE, pdFALSE },
{ 4, "STAT", ECMD_STAT, pdTRUE, pdFALSE },
{ 4, "HELP", ECMD_HELP, pdFALSE, pdFALSE },
{ 4, "NOOP", ECMD_NOOP, pdFALSE, pdFALSE },
{ 4, "EMPT", ECMD_EMPTY, pdFALSE, pdFALSE },
{ 4, "CLOS", ECMD_CLOSE, pdTRUE, pdFALSE },
{ 4, "UNKN", ECMD_UNKNOWN, pdFALSE, pdFALSE },
};

View File

@ -1,71 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "FreeRTOS_HTTP_commands.h"
const struct xWEB_COMMAND xWebCommands[ WEB_CMD_COUNT ] =
{
{ 3, "GET", ECMD_GET },
{ 4, "HEAD", ECMD_HEAD },
{ 4, "POST", ECMD_POST },
{ 3, "PUT", ECMD_PUT },
{ 6, "DELETE", ECMD_DELETE },
{ 5, "TRACE", ECMD_TRACE },
{ 7, "OPTIONS", ECMD_OPTIONS },
{ 7, "CONNECT", ECMD_CONNECT },
{ 5, "PATCH", ECMD_PATCH },
{ 4, "UNKN", ECMD_UNK },
};
const char *webCodename (int aCode)
{
switch (aCode) {
case WEB_REPLY_OK: // = 200,
return "OK";
case WEB_NO_CONTENT: // 204
return "No content";
case WEB_BAD_REQUEST: // = 400,
return "Bad request";
case WEB_UNAUTHORIZED: // = 401,
return "Authorization Required";
case WEB_NOT_FOUND: // = 404,
return "Not Found";
case WEB_GONE: // = 410,
return "Done";
case WEB_PRECONDITION_FAILED: // = 412,
return "Precondition Failed";
case WEB_INTERNAL_SERVER_ERROR: // = 500,
return "Internal Server Error";
}
return "Unknown";
}

View File

@ -1,428 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
/* Standard includes. */
#include <stdio.h>
#include <stdlib.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
/* FreeRTOS Protocol includes. */
#include "FreeRTOS_HTTP_commands.h"
#include "FreeRTOS_TCP_server.h"
#include "FreeRTOS_server_private.h"
/* Remove the whole file if HTTP is not supported. */
#if( ipconfigUSE_HTTP == 1 )
/* FreeRTOS+FAT includes. */
#include "ff_stdio.h"
#ifndef HTTP_SERVER_BACKLOG
#define HTTP_SERVER_BACKLOG ( 12 )
#endif
#ifndef USE_HTML_CHUNKS
#define USE_HTML_CHUNKS ( 0 )
#endif
#if !defined( ARRAY_SIZE )
#define ARRAY_SIZE(x) ( BaseType_t ) (sizeof( x ) / sizeof( x )[ 0 ] )
#endif
/* Some defines to make the code more readbale */
#define pcCOMMAND_BUFFER pxClient->pxParent->pcCommandBuffer
#define pcNEW_DIR pxClient->pxParent->pcNewDir
#define pcFILE_BUFFER pxClient->pxParent->pcFileBuffer
#ifndef ipconfigHTTP_REQUEST_CHARACTER
#define ipconfigHTTP_REQUEST_CHARACTER '?'
#endif
/*_RB_ Need comment block, although fairly self evident. */
static void prvFileClose( HTTPClient_t *pxClient );
static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex );
static const char *pcGetContentsType( const char *apFname );
static BaseType_t prvOpenURL( HTTPClient_t *pxClient );
static BaseType_t prvSendFile( HTTPClient_t *pxClient );
static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode );
static const char pcEmptyString[1] = { '\0' };
typedef struct xTYPE_COUPLE
{
const char *pcExtension;
const char *pcType;
} TypeCouple_t;
static TypeCouple_t pxTypeCouples[ ] =
{
{ "html", "text/html" },
{ "css", "text/css" },
{ "js", "text/javascript" },
{ "png", "image/png" },
{ "jpg", "image/jpeg" },
{ "gif", "image/gif" },
{ "txt", "text/plain" },
{ "mp3", "audio/mpeg3" },
{ "wav", "audio/wav" },
{ "flac", "audio/ogg" },
{ "pdf", "application/pdf" },
{ "ttf", "application/x-font-ttf" },
{ "ttc", "application/x-font-ttf" }
};
void vHTTPClientDelete( TCPClient_t *pxTCPClient )
{
HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient;
/* This HTTP client stops, close / release all resources. */
if( pxClient->xSocket != FREERTOS_NO_SOCKET )
{
FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_ALL );
FreeRTOS_closesocket( pxClient->xSocket );
pxClient->xSocket = FREERTOS_NO_SOCKET;
}
prvFileClose( pxClient );
}
/*-----------------------------------------------------------*/
static void prvFileClose( HTTPClient_t *pxClient )
{
if( pxClient->pxFileHandle != NULL )
{
FreeRTOS_printf( ( "Closing file: %s\n", pxClient->pcCurrentFilename ) );
ff_fclose( pxClient->pxFileHandle );
pxClient->pxFileHandle = NULL;
}
}
/*-----------------------------------------------------------*/
static BaseType_t prvSendReply( HTTPClient_t *pxClient, BaseType_t xCode )
{
struct xTCP_SERVER *pxParent = pxClient->pxParent;
BaseType_t xRc;
/* A normal command reply on the main socket (port 21). */
char *pcBuffer = pxParent->pcFileBuffer;
xRc = snprintf( pcBuffer, sizeof( pxParent->pcFileBuffer ),
"HTTP/1.1 %d %s\r\n"
#if USE_HTML_CHUNKS
"Transfer-Encoding: chunked\r\n"
#endif
"Content-Type: %s\r\n"
"Connection: keep-alive\r\n"
"%s\r\n",
( int ) xCode,
webCodename (xCode),
pxParent->pcContentsType[0] ? pxParent->pcContentsType : "text/html",
pxParent->pcExtraContents );
pxParent->pcContentsType[0] = '\0';
pxParent->pcExtraContents[0] = '\0';
xRc = FreeRTOS_send( pxClient->xSocket, ( const void * ) pcBuffer, xRc, 0 );
pxClient->bits.bReplySent = pdTRUE_UNSIGNED;
return xRc;
}
/*-----------------------------------------------------------*/
static BaseType_t prvSendFile( HTTPClient_t *pxClient )
{
size_t uxSpace;
size_t uxCount;
BaseType_t xRc = 0;
if( pxClient->bits.bReplySent == pdFALSE_UNSIGNED )
{
pxClient->bits.bReplySent = pdTRUE_UNSIGNED;
strcpy( pxClient->pxParent->pcContentsType, pcGetContentsType( pxClient->pcCurrentFilename ) );
snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
"Content-Length: %d\r\n", ( int ) pxClient->uxBytesLeft );
/* "Requested file action OK". */
xRc = prvSendReply( pxClient, WEB_REPLY_OK );
}
if( xRc >= 0 ) do
{
uxSpace = FreeRTOS_tx_space( pxClient->xSocket );
if( pxClient->uxBytesLeft < uxSpace )
{
uxCount = pxClient->uxBytesLeft;
}
else
{
uxCount = uxSpace;
}
if( uxCount > 0u )
{
if( uxCount > sizeof( pxClient->pxParent->pcFileBuffer ) )
{
uxCount = sizeof( pxClient->pxParent->pcFileBuffer );
}
ff_fread( pxClient->pxParent->pcFileBuffer, 1, uxCount, pxClient->pxFileHandle );
pxClient->uxBytesLeft -= uxCount;
xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pxParent->pcFileBuffer, uxCount, 0 );
if( xRc < 0 )
{
break;
}
}
} while( uxCount > 0u );
if( pxClient->uxBytesLeft == 0u )
{
/* Writing is ready, no need for further 'eSELECT_WRITE' events. */
FreeRTOS_FD_CLR( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
prvFileClose( pxClient );
}
else
{
/* Wake up the TCP task as soon as this socket may be written to. */
FreeRTOS_FD_SET( pxClient->xSocket, pxClient->pxParent->xSocketSet, eSELECT_WRITE );
}
return xRc;
}
/*-----------------------------------------------------------*/
static BaseType_t prvOpenURL( HTTPClient_t *pxClient )
{
BaseType_t xRc;
char pcSlash[ 2 ];
pxClient->bits.ulFlags = 0;
#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
{
if( strchr( pxClient->pcUrlData, ipconfigHTTP_REQUEST_CHARACTER ) != NULL )
{
size_t xResult;
xResult = uxApplicationHTTPHandleRequestHook( pxClient->pcUrlData, pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ) );
if( xResult > 0 )
{
strcpy( pxClient->pxParent->pcContentsType, "text/html" );
snprintf( pxClient->pxParent->pcExtraContents, sizeof( pxClient->pxParent->pcExtraContents ),
"Content-Length: %d\r\n", ( int ) xResult );
xRc = prvSendReply( pxClient, WEB_REPLY_OK ); /* "Requested file action OK" */
if( xRc > 0 )
{
xRc = FreeRTOS_send( pxClient->xSocket, pxClient->pcCurrentFilename, xResult, 0 );
}
/* Although against the coding standard of FreeRTOS, a return is
done here to simplify this conditional code. */
return xRc;
}
}
}
#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */
if( pxClient->pcUrlData[ 0 ] != '/' )
{
/* Insert a slash before the file name. */
pcSlash[ 0 ] = '/';
pcSlash[ 1 ] = '\0';
}
else
{
/* The browser provided a starting '/' already. */
pcSlash[ 0 ] = '\0';
}
snprintf( pxClient->pcCurrentFilename, sizeof( pxClient->pcCurrentFilename ), "%s%s%s",
pxClient->pcRootDir,
pcSlash,
pxClient->pcUrlData);
pxClient->pxFileHandle = ff_fopen( pxClient->pcCurrentFilename, "rb" );
FreeRTOS_printf( ( "Open file '%s': %s\n", pxClient->pcCurrentFilename,
pxClient->pxFileHandle != NULL ? "Ok" : strerror( stdioGET_ERRNO() ) ) );
if( pxClient->pxFileHandle == NULL )
{
/* "404 File not found". */
xRc = prvSendReply( pxClient, WEB_NOT_FOUND );
}
else
{
pxClient->uxBytesLeft = ( size_t ) pxClient->pxFileHandle->ulFileSize;
xRc = prvSendFile( pxClient );
}
return xRc;
}
/*-----------------------------------------------------------*/
static BaseType_t prvProcessCmd( HTTPClient_t *pxClient, BaseType_t xIndex )
{
BaseType_t xResult = 0;
/* A new command has been received. Process it. */
switch( xIndex )
{
case ECMD_GET:
xResult = prvOpenURL( pxClient );
break;
case ECMD_HEAD:
case ECMD_POST:
case ECMD_PUT:
case ECMD_DELETE:
case ECMD_TRACE:
case ECMD_OPTIONS:
case ECMD_CONNECT:
case ECMD_PATCH:
case ECMD_UNK:
{
FreeRTOS_printf( ( "prvProcessCmd: Not implemented: %s\n",
xWebCommands[xIndex].pcCommandName ) );
}
break;
}
return xResult;
}
/*-----------------------------------------------------------*/
BaseType_t xHTTPClientWork( TCPClient_t *pxTCPClient )
{
BaseType_t xRc;
HTTPClient_t *pxClient = ( HTTPClient_t * ) pxTCPClient;
if( pxClient->pxFileHandle != NULL )
{
prvSendFile( pxClient );
}
xRc = FreeRTOS_recv( pxClient->xSocket, ( void * )pcCOMMAND_BUFFER, sizeof( pcCOMMAND_BUFFER ), 0 );
if( xRc > 0 )
{
BaseType_t xIndex;
const char *pcEndOfCmd;
const struct xWEB_COMMAND *curCmd;
char *pcBuffer = pcCOMMAND_BUFFER;
if( xRc < ( BaseType_t ) sizeof( pcCOMMAND_BUFFER ) )
{
pcBuffer[ xRc ] = '\0';
}
while( xRc && ( pcBuffer[ xRc - 1 ] == 13 || pcBuffer[ xRc - 1 ] == 10 ) )
{
pcBuffer[ --xRc ] = '\0';
}
pcEndOfCmd = pcBuffer + xRc;
curCmd = xWebCommands;
/* Pointing to "/index.html HTTP/1.1". */
pxClient->pcUrlData = pcBuffer;
/* Pointing to "HTTP/1.1". */
pxClient->pcRestData = pcEmptyString;
/* Last entry is "ECMD_UNK". */
for( xIndex = 0; xIndex < WEB_CMD_COUNT - 1; xIndex++, curCmd++ )
{
BaseType_t xLength;
xLength = curCmd->xCommandLength;
if( ( xRc >= xLength ) && ( memcmp( curCmd->pcCommandName, pcBuffer, xLength ) == 0 ) )
{
char *pcLastPtr;
pxClient->pcUrlData += xLength + 1;
for( pcLastPtr = (char *)pxClient->pcUrlData; pcLastPtr < pcEndOfCmd; pcLastPtr++ )
{
char ch = *pcLastPtr;
if( ( ch == '\0' ) || ( strchr( "\n\r \t", ch ) != NULL ) )
{
*pcLastPtr = '\0';
pxClient->pcRestData = pcLastPtr + 1;
break;
}
}
break;
}
}
if( xIndex < ( WEB_CMD_COUNT - 1 ) )
{
xRc = prvProcessCmd( pxClient, xIndex );
}
}
else if( xRc < 0 )
{
/* The connection will be closed and the client will be deleted. */
FreeRTOS_printf( ( "xHTTPClientWork: rc = %ld\n", xRc ) );
}
return xRc;
}
/*-----------------------------------------------------------*/
static const char *pcGetContentsType (const char *apFname)
{
const char *slash = NULL;
const char *dot = NULL;
const char *ptr;
const char *pcResult = "text/html";
BaseType_t x;
for( ptr = apFname; *ptr; ptr++ )
{
if (*ptr == '.') dot = ptr;
if (*ptr == '/') slash = ptr;
}
if( dot > slash )
{
dot++;
for( x = 0; x < ARRAY_SIZE( pxTypeCouples ); x++ )
{
if( strcasecmp( dot, pxTypeCouples[ x ].pcExtension ) == 0 )
{
pcResult = pxTypeCouples[ x ].pcType;
break;
}
}
}
return pcResult;
}
#endif /* ipconfigUSE_HTTP */

View File

@ -1,440 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
/*
* NTPDemo.c
*
* An example of how to lookup a domain using DNS
* And also how to send and receive UDP messages to get the NTP time
*
*/
/* Standard includes. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_DNS.h"
#include "FreeRTOS_Stream_Buffer.h"
/* Use the date & time functions from +FAT. */
#include "ff_time.h"
#include "NTPDemo.h"
#include "ntpClient.h"
#include "date_and_time.h"
enum EStatus {
EStatusLookup,
EStatusAsking,
EStatusPause,
EStatusFailed,
};
static struct SNtpPacket xNTPPacket;
#if( ipconfigUSE_CALLBACKS == 0 )
static char cRecvBuffer[ sizeof( struct SNtpPacket ) + 64 ];
#endif
static enum EStatus xStatus = EStatusLookup;
static const char *pcTimeServers[] = {
"0.asia.pool.ntp.org",
"0.europe.pool.ntp.org",
"0.id.pool.ntp.org",
"0.south-america.pool.ntp.org",
"0.oceania.pool.ntp.org",
"0.north-america.pool.ntp.org"
};
static SemaphoreHandle_t xNTPWakeupSem = NULL;
static uint32_t ulIPAddressFound;
static Socket_t xUDPSocket = NULL;
static TaskHandle_t xNTPTaskhandle = NULL;
static TickType_t uxSendTime;
static void prvNTPTask( void *pvParameters );
static void vSignalTask( void )
{
#if( ipconfigUSE_CALLBACKS == 0 )
if( xUDPSocket != NULL )
{
/* Send a signal to the socket so that the
FreeRTOS_recvfrom will get interrupted. */
FreeRTOS_SignalSocket( xUDPSocket );
}
else
#endif
if( xNTPWakeupSem != NULL )
{
xSemaphoreGive( xNTPWakeupSem );
}
}
void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority )
{
/* The only public function in this module: start a task to contact
some NTP server. */
if( xNTPTaskhandle != NULL )
{
switch( xStatus )
{
case EStatusPause:
xStatus = EStatusAsking;
vSignalTask();
break;
case EStatusLookup:
FreeRTOS_printf( ( "NTP looking up server\n" ) );
break;
case EStatusAsking:
FreeRTOS_printf( ( "NTP still asking\n" ) );
break;
case EStatusFailed:
FreeRTOS_printf( ( "NTP failed somehow\n" ) );
ulIPAddressFound = 0ul;
xStatus = EStatusLookup;
vSignalTask();
break;
}
}
else
{
xUDPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
if( xUDPSocket != NULL )
{
struct freertos_sockaddr xAddress;
#if( ipconfigUSE_CALLBACKS != 0 )
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 0 );
#else
BaseType_t xReceiveTimeOut = pdMS_TO_TICKS( 5000 );
#endif
xAddress.sin_addr = 0ul;
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
FreeRTOS_bind( xUDPSocket, &xAddress, sizeof( xAddress ) );
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
xTaskCreate( prvNTPTask, /* The function that implements the task. */
( const char * ) "NTP client", /* Just a text name for the task to aid debugging. */
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
NULL, /* The task parameter, not used in this case. */
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
&xNTPTaskhandle ); /* The task handle. */
}
else
{
FreeRTOS_printf( ( "Creating socket failed\n" ) );
}
}
}
/*-----------------------------------------------------------*/
static void vDNS_callback( const char *pcName, void *pvSearchID, uint32_t ulIPAddress )
{
char pcBuf[16];
/* The DNS lookup has a result, or it has reached the time-out. */
FreeRTOS_inet_ntoa( ulIPAddress, pcBuf );
FreeRTOS_printf( ( "IP address of %s found: %s\n", pcName, pcBuf ) );
if( ulIPAddressFound == 0ul )
{
ulIPAddressFound = ulIPAddress;
}
/* For testing: in case DNS doen't respond, still try some NTP server
with a known IP-address. */
if( ulIPAddressFound == 0ul )
{
ulIPAddressFound = FreeRTOS_inet_addr_quick( 184, 105, 182, 7 );
/* ulIPAddressFound = FreeRTOS_inet_addr_quick( 103, 242, 70, 4 ); */
}
xStatus = EStatusAsking;
vSignalTask();
}
/*-----------------------------------------------------------*/
static void prvSwapFields( struct SNtpPacket *pxPacket)
{
/* NTP messages are big-endian */
pxPacket->rootDelay = FreeRTOS_htonl( pxPacket->rootDelay );
pxPacket->rootDispersion = FreeRTOS_htonl( pxPacket->rootDispersion );
pxPacket->referenceTimestamp.seconds = FreeRTOS_htonl( pxPacket->referenceTimestamp.seconds );
pxPacket->referenceTimestamp.fraction = FreeRTOS_htonl( pxPacket->referenceTimestamp.fraction );
pxPacket->originateTimestamp.seconds = FreeRTOS_htonl( pxPacket->originateTimestamp.seconds );
pxPacket->originateTimestamp.fraction = FreeRTOS_htonl( pxPacket->originateTimestamp.fraction );
pxPacket->receiveTimestamp.seconds = FreeRTOS_htonl( pxPacket->receiveTimestamp.seconds );
pxPacket->receiveTimestamp.fraction = FreeRTOS_htonl( pxPacket->receiveTimestamp.fraction );
pxPacket->transmitTimestamp.seconds = FreeRTOS_htonl( pxPacket->transmitTimestamp.seconds );
pxPacket->transmitTimestamp.fraction = FreeRTOS_htonl( pxPacket->transmitTimestamp.fraction );
}
/*-----------------------------------------------------------*/
static void prvNTPPacketInit( )
{
memset (&xNTPPacket, '\0', sizeof( xNTPPacket ) );
xNTPPacket.flags = 0xDB; /* value 0xDB : mode 3 (client), version 3, leap indicator unknown 3 */
xNTPPacket.poll = 10; /* 10 means 1 << 10 = 1024 seconds */
xNTPPacket.precision = 0xFA; /* = 250 = 0.015625 seconds */
xNTPPacket.rootDelay = 0x5D2E; /* 0x5D2E = 23854 or (23854/65535)= 0.3640 sec */
xNTPPacket.rootDispersion = 0x0008CAC8; /* 0x0008CAC8 = 8.7912 seconds */
/* use the recorded NTP time */
time_t uxSecs = FreeRTOS_time( NULL );/* apTime may be NULL, returns seconds */
xNTPPacket.referenceTimestamp.seconds = uxSecs; /* Current time */
xNTPPacket.transmitTimestamp.seconds = uxSecs + 3;
/* Transform the contents of the fields from native to big endian. */
prvSwapFields( &xNTPPacket );
}
/*-----------------------------------------------------------*/
static void prvReadTime( struct SNtpPacket * pxPacket )
{
FF_TimeStruct_t xTimeStruct;
time_t uxPreviousSeconds;
time_t uxPreviousMS;
time_t uxCurrentSeconds;
time_t uxCurrentMS;
const char *pcTimeUnit;
int32_t ilDiff;
TickType_t uxTravelTime;
uxTravelTime = xTaskGetTickCount() - uxSendTime;
/* Transform the contents of the fields from big to native endian. */
prvSwapFields( pxPacket );
uxCurrentSeconds = pxPacket->receiveTimestamp.seconds - TIME1970;
uxCurrentMS = pxPacket->receiveTimestamp.fraction / 4294967;
uxCurrentSeconds += uxCurrentMS / 1000;
uxCurrentMS = uxCurrentMS % 1000;
// Get the last time recorded
uxPreviousSeconds = FreeRTOS_get_secs_msec( &uxPreviousMS );
// Set the new time with precision in msec. */
FreeRTOS_set_secs_msec( &uxCurrentSeconds, &uxCurrentMS );
if( uxCurrentSeconds >= uxPreviousSeconds )
{
ilDiff = ( int32_t ) ( uxCurrentSeconds - uxPreviousSeconds );
}
else
{
ilDiff = 0 - ( int32_t ) ( uxPreviousSeconds - uxCurrentSeconds );
}
if( ( ilDiff < -5 ) || ( ilDiff > 5 ) )
{
/* More than 5 seconds difference. */
pcTimeUnit = "sec";
}
else
{
/* Less than or equal to 5 second difference. */
pcTimeUnit = "ms";
uint32_t ulLowest = ( uxCurrentSeconds <= uxPreviousSeconds ) ? uxCurrentSeconds : uxPreviousSeconds;
int32_t iCurMS = 1000 * ( uxCurrentSeconds - ulLowest ) + uxCurrentMS;
int32_t iPrevMS = 1000 * ( uxPreviousSeconds - ulLowest ) + uxPreviousMS;
ilDiff = iCurMS - iPrevMS;
}
uxCurrentSeconds -= iTimeZone;
FreeRTOS_gmtime_r( &uxCurrentSeconds, &xTimeStruct );
/*
378.067 [NTP client] NTP time: 9/11/2015 16:11:19.559 Diff -20 ms (289 ms)
379.441 [NTP client] NTP time: 9/11/2015 16:11:20.933 Diff 0 ms (263 ms)
*/
FreeRTOS_printf( ("NTP time: %d/%d/%02d %2d:%02d:%02d.%03u Diff %d %s (%lu ms)\n",
xTimeStruct.tm_mday,
xTimeStruct.tm_mon + 1,
xTimeStruct.tm_year + 1900,
xTimeStruct.tm_hour,
xTimeStruct.tm_min,
xTimeStruct.tm_sec,
( unsigned )uxCurrentMS,
( unsigned )ilDiff,
pcTimeUnit,
uxTravelTime ) );
/* Remove compiler warnings in case FreeRTOS_printf() is not used. */
( void ) pcTimeUnit;
( void ) uxTravelTime;
}
/*-----------------------------------------------------------*/
#if( ipconfigUSE_CALLBACKS != 0 )
static BaseType_t xOnUDPReceive( Socket_t xSocket, void * pvData, size_t xLength,
const struct freertos_sockaddr *pxFrom, const struct freertos_sockaddr *pxDest )
{
if( xLength >= sizeof( xNTPPacket ) )
{
prvReadTime( ( struct SNtpPacket *)pvData );
if( xStatus != EStatusPause )
{
xStatus = EStatusPause;
}
}
vSignalTask();
/* Tell the driver not to store the RX data */
return 1;
}
/*-----------------------------------------------------------*/
#endif /* ipconfigUSE_CALLBACKS != 0 */
static void prvNTPTask( void *pvParameters )
{
BaseType_t xServerIndex = 3;
struct freertos_sockaddr xAddress;
#if( ipconfigUSE_CALLBACKS != 0 )
F_TCP_UDP_Handler_t xHandler;
#endif /* ipconfigUSE_CALLBACKS != 0 */
xStatus = EStatusLookup;
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 ) || ( ipconfigUSE_CALLBACKS != 0 )
{
xNTPWakeupSem = xSemaphoreCreateBinary();
}
#endif
#if( ipconfigUSE_CALLBACKS != 0 )
{
memset( &xHandler, '\0', sizeof( xHandler ) );
xHandler.pxOnUDPReceive = xOnUDPReceive;
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_UDP_RECV_HANDLER, ( void * ) &xHandler, sizeof( xHandler ) );
}
#endif
#if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
{
FreeRTOS_setsockopt( xUDPSocket, 0, FREERTOS_SO_SET_SEMAPHORE, ( void * ) &xNTPWakeupSem, sizeof( xNTPWakeupSem ) );
}
#endif
for( ; ; )
{
switch( xStatus )
{
case EStatusLookup:
if( ( ulIPAddressFound == 0ul ) || ( ulIPAddressFound == ~0ul ) )
{
if( ++xServerIndex == sizeof( pcTimeServers ) / sizeof( pcTimeServers[ 0 ] ) )
{
xServerIndex = 0;
}
FreeRTOS_printf( ( "Looking up server '%s'\n", pcTimeServers[ xServerIndex ] ) );
FreeRTOS_gethostbyname_a( pcTimeServers[ xServerIndex ], vDNS_callback, (void *)NULL, 1200 );
}
else
{
xStatus = EStatusAsking;
}
break;
case EStatusAsking:
{
char pcBuf[16];
prvNTPPacketInit( );
xAddress.sin_addr = ulIPAddressFound;
xAddress.sin_port = FreeRTOS_htons( NTP_PORT );
FreeRTOS_inet_ntoa( xAddress.sin_addr, pcBuf );
FreeRTOS_printf( ( "Sending UDP message to %s:%u\n",
pcBuf,
FreeRTOS_ntohs( xAddress.sin_port ) ) );
uxSendTime = xTaskGetTickCount( );
FreeRTOS_sendto( xUDPSocket, ( void * )&xNTPPacket, sizeof( xNTPPacket ), 0, &xAddress, sizeof( xAddress ) );
}
break;
case EStatusPause:
break;
case EStatusFailed:
break;
}
#if( ipconfigUSE_CALLBACKS != 0 )
{
xSemaphoreTake( xNTPWakeupSem, 5000 );
}
#else
{
uint32_t xAddressSize;
BaseType_t xReturned;
xAddressSize = sizeof( xAddress );
xReturned = FreeRTOS_recvfrom( xUDPSocket, ( void * ) cRecvBuffer, sizeof( cRecvBuffer ), 0, &xAddress, &xAddressSize );
switch( xReturned )
{
case 0:
case -pdFREERTOS_ERRNO_EAGAIN:
case -pdFREERTOS_ERRNO_EINTR:
break;
default:
if( xReturned < sizeof( xNTPPacket ) )
{
FreeRTOS_printf( ( "FreeRTOS_recvfrom: returns %ld\n", xReturned ) );
}
else
{
prvReadTime( ( struct SNtpPacket *)cRecvBuffer );
if( xStatus != EStatusPause )
{
xStatus = EStatusPause;
}
}
break;
}
}
#endif
}
}
/*-----------------------------------------------------------*/

View File

@ -1,133 +0,0 @@
/*
* FreeRTOS+TCP V2.0.1
* Copyright (C) 2017 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
*/
#ifndef __FTPCMD_H__
#define __FTPCMD_H__
#define REPL_110 "110 Restart marker reply.\r\n"
#define REPL_120 "120 Try again in 2 minutes.\r\n"
#define REPL_125 "125 Data connection already open; transfer starting.\r\n"
#define REPL_150 "150 File status okay; about to open data connection.\r\n"
#define REPL_200 "200 NOOP command successful.\r\n"
#define REPL_200_PROGRESS "200 NOOP: data transfer in progress.\r\n"
#define REPL_202 "202 Command not implemented, superfluous at this site.\r\n"
#define REPL_211 "221 System status, or system help reply.\r\n"
#define REPL_211_STATUS "221-status of %s.\r\n"
#define REPL_211_END "221 End of status.\r\n"
#define REPL_212 "212 Directory status.\r\n"
#define REPL_213 "213 File status.\r\n"
#define REPL_214 "214 Help message.\r\n"
#define REPL_214_END "214 End Help message.\r\n"
#define REPL_215 "215 %s system type.\r\n"
#define REPL_220 "220 Service ready for new user.\r\n"
#define REPL_221 "221 Service closing control connection.\r\n"
#define REPL_225 "225 Data connection open; no transfer in progress.\r\n"
#define REPL_226 "226 Closing data connection.\r\n"
#define REPL_227 "227 Entering Passive Mode (%s,%s,%s,%s,%s,%s).\r\n"
#define REPL_227_D "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u).\r\n"
#define REPL_230 "230 User logged in, proceed.\r\n"
#define REPL_250 "250 Requested file action okay, completed.\r\n"
#define REPL_257 "257 %s created.\r\n"
// #define REPL_257_PWD "257 \"%s\" is current working dir.\r\n"
#define REPL_257_PWD "257 \"%s\"\r\n"
#define REPL_331 "331 Only anonymous user is accepted.\r\n"
#define REPL_331_ANON "331 Anonymous login okay\r\n"
#define REPL_332 "332 Need account for login.\r\n"
#define REPL_350 "350 Requested file action pending further information.\r\n"
#define REPL_421 "421 Service not available, closing control connection.\r\n"
#define REPL_425 "425 Can't open data connection.\r\n"
#define REPL_426 "426 Connection closed; transfer aborted.\r\n"
#define REPL_450 "450 Requested file action not taken.\r\n"
#define REPL_451 "451 Requested action aborted. Local error in processing.\r\n"
#define REPL_452 "452 Requested action not taken.\r\n"
#define REPL_500 "500 Syntax error, command unrecognized.\r\n"
#define REPL_501 "501 Syntax error in parameters or arguments.\r\n"
#define REPL_502 "502 Command not implemented.\r\n"
#define REPL_503 "503 Bad sequence of commands.\r\n"
#define REPL_504 "504 Command not implemented for that parameter.\r\n"
#define REPL_530 "530 Not logged in.\r\n"
#define REPL_532 "532 Need account for storing files.\r\n"
#define REPL_550 "550 Requested action not taken.\r\n"
#define REPL_551 "551 Requested action aborted. Page type unknown.\r\n"
#define REPL_552 "552 Requested file action aborted.\r\n"
#define REPL_553 "553 Requested action not taken.\r\n"
#define REPL_553_READ_ONLY "553 Read-only file-system.\r\n"
enum EFTPCommand {
ECMD_USER,
ECMD_PASS,
ECMD_ACCT,
ECMD_CWD,
ECMD_CDUP,
ECMD_SMNT,
ECMD_QUIT,
ECMD_REIN,
ECMD_PORT,
ECMD_PASV,
ECMD_TYPE,
ECMD_STRU,
ECMD_MODE,
ECMD_RETR,
ECMD_STOR,
ECMD_STOU,
ECMD_APPE,
ECMD_ALLO,
ECMD_REST,
ECMD_RNFR,
ECMD_RNTO,
ECMD_ABOR,
ECMD_SIZE,
ECMD_MDTM,
ECMD_DELE,
ECMD_RMD,
ECMD_MKD,
ECMD_PWD,
ECMD_LIST,
ECMD_NLST,
ECMD_SITE,
ECMD_SYST,
ECMD_FEAT,
ECMD_STAT,
ECMD_HELP,
ECMD_NOOP,
ECMD_EMPTY,
ECMD_CLOSE,
ECMD_UNKNOWN,
};
typedef struct xFTP_COMMAND {
BaseType_t xCommandLength;
const char pcCommandName[7];
const unsigned char ucCommandType;
const unsigned char checkLogin;
const unsigned char checkNullArg;
} FTPCommand_t;
#define FTP_CMD_COUNT (ECMD_UNKNOWN+1)
extern const FTPCommand_t xFTPCommands[ FTP_CMD_COUNT ];
#endif // __FTPCMD_H__

View File

@ -1,67 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
#ifndef FREERTOS_HTTP_COMMANDS_H
#define FREERTOS_HTTP_COMMANDS_H
enum {
WEB_REPLY_OK = 200,
WEB_NO_CONTENT = 204,
WEB_BAD_REQUEST = 400,
WEB_UNAUTHORIZED = 401,
WEB_NOT_FOUND = 404,
WEB_GONE = 410,
WEB_PRECONDITION_FAILED = 412,
WEB_INTERNAL_SERVER_ERROR = 500,
};
enum EWebCommand {
ECMD_GET,
ECMD_HEAD,
ECMD_POST,
ECMD_PUT,
ECMD_DELETE,
ECMD_TRACE,
ECMD_OPTIONS,
ECMD_CONNECT,
ECMD_PATCH,
ECMD_UNK,
};
struct xWEB_COMMAND
{
BaseType_t xCommandLength;
const char *pcCommandName;
const unsigned char ucCommandType;
};
#define WEB_CMD_COUNT (ECMD_UNK+1)
extern const struct xWEB_COMMAND xWebCommands[WEB_CMD_COUNT];
extern const char *webCodename (int aCode);
#endif /* FREERTOS_HTTP_COMMANDS_H */

View File

@ -1,125 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
/*
Some code which is common to TCP servers like HTTP en FTP
*/
#ifndef FREERTOS_TCP_SERVER_H
#define FREERTOS_TCP_SERVER_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FTP_SERVER_USES_RELATIVE_DIRECTORY
#define FTP_SERVER_USES_RELATIVE_DIRECTORY 0
#endif
enum eSERVER_TYPE
{
eSERVER_NONE,
eSERVER_HTTP,
eSERVER_FTP,
};
struct xFTP_CLIENT;
#if( ipconfigFTP_HAS_RECEIVED_HOOK != 0 )
extern void vApplicationFTPReceivedHook( const char *pcFileName, uint32_t ulSize, struct xFTP_CLIENT *pxFTPClient );
extern void vFTPReplyMessage( struct xFTP_CLIENT *pxFTPClient, const char *pcMessage );
#endif /* ipconfigFTP_HAS_RECEIVED_HOOK != 0 */
#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 )
/*
* Function is called when a user name has been submitted.
* The function may return a string such as: "331 Please enter your password"
* or return NULL to use the default reply.
*/
extern const char *pcApplicationFTPUserHook( const char *pcUserName );
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
#if( ipconfigFTP_HAS_USER_PASSWORD_HOOK != 0 )
/*
* Function is called when a password was received.
* Return positive value to allow the user
*/
extern BaseType_t xApplicationFTPPasswordHook( const char *pcUserName, const char *pcPassword );
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
#if( ipconfigFTP_HAS_USER_PROPERTIES_HOOK != 0 )
/*
* The FTP server is asking for user-specific properties
*/
typedef struct
{
uint16_t usPortNumber; /* For reference only. Host-endian. */
const char *pcRootDir;
BaseType_t xReadOnly;
}
FTPUserProperties_t;
extern void vApplicationFTPUserPropertiesHook( const char *pcUserName, FTPUserProperties_t *pxProperties );
#endif /* ipconfigFTP_HAS_USER_PASSWORD_HOOK */
#if( ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK != 0 )
/*
* A GET request is received containing a special character,
* usually a question mark.
* const char *pcURLData; // A request, e.g. "/request?limit=75"
* char *pcBuffer; // Here the answer can be written
* size_t uxBufferLength; // Size of the buffer
*
*/
extern size_t uxApplicationHTTPHandleRequestHook( const char *pcURLData, char *pcBuffer, size_t uxBufferLength );
#endif /* ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK */
struct xSERVER_CONFIG
{
enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */
BaseType_t xPortNumber; /* e.g. 80, 8080, 21 */
BaseType_t xBackLog; /* e.g. 10, maximum number of connected TCP clients */
const char * const pcRootDir; /* Treat this directory as the root directory */
};
struct xTCP_SERVER;
typedef struct xTCP_SERVER TCPServer_t;
TCPServer_t *FreeRTOS_CreateTCPServer( const struct xSERVER_CONFIG *pxConfigs, BaseType_t xCount );
void FreeRTOS_TCPServerWork( TCPServer_t *pxServer, TickType_t xBlockingTime );
#if( ipconfigSUPPORT_SIGNALS != 0 )
/* FreeRTOS_TCPServerWork() calls select().
The two functions below provide a possibility to interrupt
the call to select(). After the interruption, resume
by calling FreeRTOS_TCPServerWork() again. */
BaseType_t FreeRTOS_TCPServerSignal( TCPServer_t *pxServer );
BaseType_t FreeRTOS_TCPServerSignalFromISR( TCPServer_t *pxServer, BaseType_t *pxHigherPriorityTaskWoken );
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* FREERTOS_TCP_SERVER_H */

View File

@ -1,185 +0,0 @@
/*
* FreeRTOS+TCP V2.0.3
* Copyright (C) 2017 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
*/
/*
Some code which is common to TCP servers like HTTP and FTP
*/
#ifndef FREERTOS_SERVER_PRIVATE_H
#define FREERTOS_SERVER_PRIVATE_H
#define FREERTOS_NO_SOCKET NULL
/* FreeRTOS+FAT */
#include "ff_stdio.h"
/* Each HTTP server has 1, at most 2 sockets */
#define HTTP_SOCKET_COUNT 2
/*
* ipconfigTCP_COMMAND_BUFFER_SIZE sets the size of:
* pcCommandBuffer': a buffer to receive and send TCP commands
*
* ipconfigTCP_FILE_BUFFER_SIZE sets the size of:
* pcFileBuffer' : a buffer to access the file system: read or write data.
*
* The buffers are both used for FTP as well as HTTP.
*/
#ifndef ipconfigTCP_COMMAND_BUFFER_SIZE
#define ipconfigTCP_COMMAND_BUFFER_SIZE ( 2048 )
#endif
#ifndef ipconfigTCP_FILE_BUFFER_SIZE
#define ipconfigTCP_FILE_BUFFER_SIZE ( 2048 )
#endif
struct xTCP_CLIENT;
typedef BaseType_t ( * FTCPWorkFunction ) ( struct xTCP_CLIENT * /* pxClient */ );
typedef void ( * FTCPDeleteFunction ) ( struct xTCP_CLIENT * /* pxClient */ );
#define TCP_CLIENT_FIELDS \
enum eSERVER_TYPE eType; \
struct xTCP_SERVER *pxParent; \
Socket_t xSocket; \
const char *pcRootDir; \
FTCPWorkFunction fWorkFunction; \
FTCPDeleteFunction fDeleteFunction; \
struct xTCP_CLIENT *pxNextClient
typedef struct xTCP_CLIENT
{
/* This define contains fields which must come first within each of the client structs */
TCP_CLIENT_FIELDS;
/* --- Keep at the top --- */
} TCPClient_t;
struct xHTTP_CLIENT
{
/* This define contains fields which must come first within each of the client structs */
TCP_CLIENT_FIELDS;
/* --- Keep at the top --- */
const char *pcUrlData;
const char *pcRestData;
char pcCurrentFilename[ ffconfigMAX_FILENAME ];
size_t uxBytesLeft;
FF_FILE *pxFileHandle;
union {
struct {
uint32_t
bReplySent : 1;
};
uint32_t ulFlags;
} bits;
};
typedef struct xHTTP_CLIENT HTTPClient_t;
struct xFTP_CLIENT
{
/* This define contains fields which must come first within each of the client structs */
TCP_CLIENT_FIELDS;
/* --- Keep at the top --- */
uint32_t ulRestartOffset;
uint32_t ulRecvBytes;
size_t uxBytesLeft; /* Bytes left to send */
uint32_t ulClientIP;
TickType_t xStartTime;
uint16_t usClientPort;
Socket_t xTransferSocket;
BaseType_t xTransType;
BaseType_t xDirCount;
FF_FindData_t xFindData;
FF_FILE *pxReadHandle;
FF_FILE *pxWriteHandle;
char pcCurrentDir[ ffconfigMAX_FILENAME ];
char pcFileName[ ffconfigMAX_FILENAME ];
char pcConnectionAck[ 128 ];
char pcClientAck[ 128 ];
union {
struct {
uint32_t
bHelloSent : 1,
bLoggedIn : 1,
bStatusUser : 1,
bInRename : 1,
bReadOnly : 1;
};
uint32_t ulFTPFlags;
} bits;
union {
struct {
uint32_t
bIsListen : 1, /* pdTRUE for passive data connections (using list()). */
bDirHasEntry : 1, /* pdTRUE if ff_findfirst() was successful. */
bClientConnected : 1, /* pdTRUE after connect() or accept() has succeeded. */
bEmptyFile : 1, /* pdTRUE if a connection-without-data was received. */
bHadError : 1; /* pdTRUE if a transfer got aborted because of an error. */
};
uint32_t ulConnFlags;
} bits1;
};
typedef struct xFTP_CLIENT FTPClient_t;
BaseType_t xHTTPClientWork( TCPClient_t *pxClient );
BaseType_t xFTPClientWork( TCPClient_t *pxClient );
void vHTTPClientDelete( TCPClient_t *pxClient );
void vFTPClientDelete( TCPClient_t *pxClient );
BaseType_t xMakeAbsolute( struct xFTP_CLIENT *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName );
BaseType_t xMakeRelative( FTPClient_t *pxClient, char *pcBuffer, BaseType_t xBufferLength, const char *pcFileName );
struct xTCP_SERVER
{
SocketSet_t xSocketSet;
/* A buffer to receive and send TCP commands, either HTTP of FTP. */
char pcCommandBuffer[ ipconfigTCP_COMMAND_BUFFER_SIZE ];
/* A buffer to access the file system: read or write data. */
char pcFileBuffer[ ipconfigTCP_FILE_BUFFER_SIZE ];
#if( ipconfigUSE_FTP != 0 )
char pcNewDir[ ffconfigMAX_FILENAME ];
#endif
#if( ipconfigUSE_HTTP != 0 )
char pcContentsType[40]; /* Space for the msg: "text/javascript" */
char pcExtraContents[40]; /* Space for the msg: "Content-Length: 346500" */
#endif
BaseType_t xServerCount;
TCPClient_t *pxClients;
struct xSERVER
{
enum eSERVER_TYPE eType; /* eSERVER_HTTP | eSERVER_FTP */
const char *pcRootDir;
Socket_t xSocket;
} xServers[ 1 ];
};
#endif /* FREERTOS_SERVER_PRIVATE_H */

View File

@ -1,71 +0,0 @@
//
// ntpClient.h
//
#ifndef __NTPCLIENT_H__
#define __NTPCLIENT_H__
#define NTP_PORT 123
typedef uint32_t quint32;
typedef int32_t qint32;
typedef uint8_t quint8;
typedef int8_t qint8;
typedef union _SNtpFlags SNtpFlags;
/**
* 64-bit NTP timestamp.
*/
struct __attribute__ ((__packed__)) _SNtpTimestamp {
/** Number of seconds passed since Jan 1 1900, in big-endian format. */
quint32 seconds;
/** Fractional time part, in <tt>1/0xFFFFFFFF</tt>s of a second. */
quint32 fraction;
};
typedef struct _SNtpTimestamp SNtpTimestamp;
/**
* Mandatory part of an NTP packet
*/
struct SNtpPacket {
/** Flags. */
unsigned char flags; // value 0xDB : mode 3 (client), version 3, leap indicator unknown 3
/** Stratum of the clock. */
quint8 stratum; // value 0 : unspecified
/** Maximum interval between successive messages, in log2 seconds. Note that the value is signed. */
qint8 poll; // 10 means 1 << 10 = 1024 seconds
/** Precision of the clock, in log2 seconds. Note that the value is signed. */
qint8 precision; // 0xFA = 250 = 0.015625 seconds
/** Round trip time to the primary reference source, in NTP short format. */
qint32 rootDelay; // 0x5D2E = 23854 or (23854/65535)= 0.3640 sec
/** Nominal error relative to the primary reference source. */
qint32 rootDispersion; // 0x0008 CAC8 = 8.7912 seconds
/** Reference identifier (either a 4 character string or an IP address). */
qint8 referenceID[4]; // or just 0000
/** The time at which the clock was last set or corrected. */
SNtpTimestamp referenceTimestamp; // Current time
/** The time at which the request departed the client for the server. */
SNtpTimestamp originateTimestamp; // Keep 0
/** The time at which the request arrived at the server. */
SNtpTimestamp receiveTimestamp; // Keep 0
/** The time at which the reply departed the server for client. */
SNtpTimestamp transmitTimestamp;
};
/* Add this number to get secs since 1-1-1900 */
#define TIME1970 2208988800UL
#endif // __NTPCLIENT_H__

View File

@ -1,11 +0,0 @@
/*
* A simple demo for NTP using FreeRTOS+TCP
*/
#ifndef NTPDEMO_H
#define NTPDEMO_H
void vStartNTPTask( uint16_t usTaskStackSize, UBaseType_t uxTaskPriority );
#endif