From f99d299ee374d53b2de76a8c920812ef10859b48 Mon Sep 17 00:00:00 2001 From: rtel Date: Wed, 22 Aug 2018 21:29:21 +0000 Subject: [PATCH] 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. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2563 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Common/FreeRTOS_TCP_server.c | 0 .../FTP/FreeRTOS_FTP_commands.c | 0 .../FTP/FreeRTOS_FTP_server.c | 0 .../HTTP/FreeRTOS_HTTP_commands.c | 0 .../HTTP/FreeRTOS_HTTP_server.c | 0 .../Common/Demo_IP_Protocols}/NTP/NTPDemo.c | 0 .../include/FreeRTOS_FTP_commands.h | 0 .../include/FreeRTOS_HTTP_commands.h | 0 .../include/FreeRTOS_TCP_server.h | 0 .../include/FreeRTOS_server_private.h | 0 .../Demo_IP_Protocols}/include/NTPClient.h | 0 .../Demo_IP_Protocols}/include/NTPDemo.h | 0 .../Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c | 9 +- .../Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c | 175 +- .../Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c | 582 ++-- .../Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c | 339 +- .../FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c | 207 +- .../FreeRTOS_Stream_Buffer.c | 2 +- .../FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c | 449 ++- .../FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c | 47 +- .../FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c | 38 +- .../Source/FreeRTOS-Plus-TCP/History.txt | 9 +- .../include/FreeRTOSIPConfigDefaults.h | 17 +- .../FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h | 2 +- .../FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h | 2 +- .../FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h | 2 +- .../FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h | 2 +- .../include/FreeRTOS_IP_Private.h | 16 +- .../include/FreeRTOS_Sockets.h | 2 +- .../include/FreeRTOS_Stream_Buffer.h | 2 +- .../include/FreeRTOS_TCP_IP.h | 2 +- .../include/FreeRTOS_TCP_WIN.h | 17 +- .../include/FreeRTOS_UDP_IP.h | 2 +- .../include/FreeRTOS_errno_TCP.h | 2 +- .../include/IPTraceMacroDefaults.h | 2 +- .../include/NetworkBufferManagement.h | 2 +- .../include/NetworkInterface.h | 2 +- .../BufferManagement/BufferAllocation_1.c | 49 +- .../BufferManagement/BufferAllocation_2.c | 22 +- .../portable/Compiler/GCC/pack_struct_end.h | 47 +- .../portable/Compiler/GCC/pack_struct_start.h | 47 +- .../portable/Compiler/IAR/pack_struct_end.h | 47 +- .../portable/Compiler/IAR/pack_struct_start.h | 47 +- .../portable/Compiler/MSVC/pack_struct_end.h | 47 +- .../Compiler/MSVC/pack_struct_start.h | 47 +- .../Compiler/Renesas/pack_struct_end.h | 47 +- .../Compiler/Renesas/pack_struct_start.h | 47 +- .../LPC17xx/NetworkInterface.c | 47 +- .../NetworkInterface/SH2A/NetworkInterface.c | 47 +- .../STM32Fxx/NetworkInterface.c | 13 +- .../WinPCap/NetworkInterface.c | 87 +- .../NetworkInterface/Zynq/NetworkInterface.c | 47 +- .../NetworkInterface/Zynq/x_emacpsif_dma.c | 46 +- .../ksz8851snl/NetworkInterface.c | 47 +- .../RTOSDemo.ewp | 11 +- .../settings/RTOSDemo.sram.cspy.bat | 4 +- .../settings/RTOSDemo.sram.driver.xcl | 2 +- .../settings/RTOSDemo.sram.general.xcl | 6 +- .../settings/RTOSDemo.wsdt | 49 +- .../RTOSDemo.ewd | 2794 +++++++++-------- .../RTOSDemo.ewp | 2427 +++++++------- .../settings/RTOSDemo.crun | 25 +- .../settings/RTOSDemo.dbgdt | 445 ++- .../settings/RTOSDemo.sram.cspy.bat | 18 +- .../settings/RTOSDemo.wsdt | 682 +++- .../CORTEX_A5_SAMA5D4x_EK_IAR/RTOSDemo.ewp | 21 +- .../settings/RTOSDemo.wsdt | 41 +- .../Demo/CORTEX_R4_RM48_TMS570_CCS5/.cproject | 63 +- 68 files changed, 5356 insertions(+), 3944 deletions(-) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/Common/FreeRTOS_TCP_server.c (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/FTP/FreeRTOS_FTP_commands.c (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/FTP/FreeRTOS_FTP_server.c (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/HTTP/FreeRTOS_HTTP_commands.c (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/HTTP/FreeRTOS_HTTP_server.c (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/NTP/NTPDemo.c (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/include/FreeRTOS_FTP_commands.h (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/include/FreeRTOS_HTTP_commands.h (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/include/FreeRTOS_TCP_server.h (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/include/FreeRTOS_server_private.h (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/include/NTPClient.h (100%) rename FreeRTOS-Plus/{Source/FreeRTOS-Plus-TCP/protocols => Demo/Common/Demo_IP_Protocols}/include/NTPDemo.h (100%) diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/Common/FreeRTOS_TCP_server.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/Common/FreeRTOS_TCP_server.c rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/Common/FreeRTOS_TCP_server.c diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/FTP/FreeRTOS_FTP_commands.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/FTP/FreeRTOS_FTP_commands.c rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_commands.c diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/FTP/FreeRTOS_FTP_server.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/FTP/FreeRTOS_FTP_server.c rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/FTP/FreeRTOS_FTP_server.c diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/HTTP/FreeRTOS_HTTP_commands.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_commands.c similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/HTTP/FreeRTOS_HTTP_commands.c rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_commands.c diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/HTTP/FreeRTOS_HTTP_server.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_server.c similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/HTTP/FreeRTOS_HTTP_server.c rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/HTTP/FreeRTOS_HTTP_server.c diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/NTP/NTPDemo.c b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/NTP/NTPDemo.c rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/NTP/NTPDemo.c diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_FTP_commands.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_FTP_commands.h rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_FTP_commands.h diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_HTTP_commands.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_HTTP_commands.h rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_HTTP_commands.h diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_TCP_server.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_TCP_server.h rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_TCP_server.h diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_server_private.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/FreeRTOS_server_private.h rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/FreeRTOS_server_private.h diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/NTPClient.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/NTPClient.h rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPClient.h diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/NTPDemo.h b/FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h similarity index 100% rename from FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/protocols/include/NTPDemo.h rename to FreeRTOS-Plus/Demo/Common/Demo_IP_Protocols/include/NTPDemo.h diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c index 710093a90..b31b76894 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c @@ -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 ); diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c index 8ce9e8e92..eef8ec848 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c @@ -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++; - } - - /* 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 ); - } + /* 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; + + /* 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; - /* 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 ) ); + /* 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. */ + 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(); diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c index e14e7d212..894b7240d 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c @@ -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++; - - /* 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( 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 - - if( ulIPAddress == 0UL) - { - ulIPAddress = prvGetHostByName( pcHostName, xIdentifier, xReadTimeOut_ms ); - } - - return ulIPAddress; +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 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 */ + + /* Generate a unique identifier. */ + if( 0 == ulIPAddress ) + { + xIdentifier = ( TickType_t )ipconfigRAND32( ); + } + + #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 + + 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 ); - } - - #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 ); + pucByte = prvSkipNameField( pucByte, + xSourceBytesRemaining ); + + /* Check for a malformed response. */ + if( NULL == pucByte ) + { + return dnsPARSE_ERROR; + } + else + { + xSourceBytesRemaining = pucUDPPayloadBuffer + xBufferLength - pucByte; + } + } + + /* 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 ); + 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 ); - - /* Is the type field that of an A record? */ - if( usChar2u16( pucByte ) == dnsTYPE_A_HOST ) + pucByte = prvSkipNameField( pucByte, + xSourceBytesRemaining ); + + /* 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 ) ); - - /* 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 ); + /* 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 ); + + /* 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; - - xFreeEntry++; - if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES ) - { - xFreeEntry = 0; - } + /* Add or update the item. */ + if( strlen( pcName ) < ipconfigDNS_CACHE_NAME_LENGTH ) + { + strcpy( xDNSCache[ xFreeEntry ].pcName, pcName ); + + 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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c index 7f311ade8..fdb8fd116 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c @@ -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( 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; - - case ipIPv4_FRAME_TYPE : - /* The Ethernet frame contains an IP packet. */ - eReturned = prvProcessIPPacket( ( IPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer ); - break; - - default : - /* No other packet types are handled. Nothing to do. */ - eReturned = eReleaseBuffer; - break; - } - } + 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. */ + 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. */ + 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; + } + } + } /* 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; - - /* 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; - } + /* 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 ); + } + + /* 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 ); } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c index be8dec62c..6ad9a86d3 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c @@ -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 ); - - /* 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; + vListInitialise( &xBoundUDPSocketsList ); - ulNextInitialSequenceNumber = ipconfigRAND32(); + #if( ipconfigUSE_TCP == 1 ) + { + vListInitialise( &xBoundTCPSocketsList ); + } + #endif /* ipconfigUSE_TCP == 1 */ - /* 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 ] ); - - 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; - } - - usResult = FreeRTOS_htons( usNextPortToUse[ xIndex ] ); - - if( pxListFindListItemWithValue( pxList, ( TickType_t ) usResult ) == NULL ) - { - break; - } - } - return usResult; -} /* Tested */ + /* Find the next available port using the random seed as a starting + point. */ + do + { + /* Generate a random seed. */ + ulRandomSeed = ipconfigRAND32( ); + + /* Only proceed if the random number generator succeeded. */ + if( 0 == ulRandomSeed ) + { + if( pdFALSE == xGotZeroOnce ) + { + xGotZeroOnce = pdTRUE; + continue; + } + else + { + break; + } + } + + /* Map the random to a candidate port. */ + usResult = + socketAUTO_PORT_ALLOCATION_START_NUMBER + + ( ( ( uint16_t )ulRandomSeed ) % usEphemeralPortCount ); + + /* 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. */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c index 91e5fae03..7729582e5 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c index 614829ff9..b8a6be04e 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c @@ -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,31 +998,46 @@ 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 ] ) ); - - /* And issue a (new) ARP request */ - FreeRTOS_OutputARPRequest( ulRemoteIP ); - - xReturn = pdFALSE; - break; - } + 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 ); + + 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 ) { @@ -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 ) ) - { - /* An MSS option with the correct option length. FreeRTOS_htons() + else if( pucPtr[ 0 ] == TCP_OPT_MSS ) + { + /* 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( 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( 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( ( 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( 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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c index 556482a82..11dc00f01 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c @@ -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 ); - - if ( pxFound != NULL ) - { - /* Remove it because it will be passed to user directly. */ - vTCPWindowFree( pxFound ); - } - } while ( pxFound ); + /* 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 ); /* Check for following segments that are already in the queue and increment ulCurrentSequenceNumber. */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c index 8262a5104..94a8e17f8 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c @@ -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 ) ) ) { diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt index fd3ba86fa..b485a2833 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt @@ -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. diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h index 36781cca5..dd8ae07f4 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h index 1eb700cc1..5f7e7871f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h index 39c1b9239..3cdb4b6a8 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h index 10d35779d..9ab08873e 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h index 6fd33585f..11342aeeb 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h index 518c20e92..254201d19 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h index c51ad5aee..a8a5710b7 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h index bbdc55e0f..1d088e716 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h index 26e729b9e..4a7aa00f9 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h index 7f7f6c0df..74bb71ebc 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h @@ -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' */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h index 1b0dc55c5..ca70b3abd 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h index 8a92b289b..bb405eaf9 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h index a8818207e..6f1f5e360 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h index f2397e359..e05f0ac8f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h index 58118465d..f5f246503 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c index 6ac78afad..f8b04e420 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c @@ -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(); { diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c index 467e5b86b..e158e39bb 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c @@ -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 ); } /*-----------------------------------------------------------*/ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h index a122660d7..606f7df15 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h index 34926c288..8893ec01f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h index 185de8b35..104ecef17 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h index 2be3bcac8..f012d9988 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h index 4ab7f753b..54dffdde5 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h index 5ef2b5d14..f133207cb 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h index afe5be971..b49313602 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h index d1ae7f94d..9436de7de 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h @@ -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 +*/ /***************************************************************************** * diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c index d96ff29c6..7799731b4 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c index cb554f426..de077131f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c index 4e13ee3f0..268273cd9 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c @@ -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. */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c index cca53970e..86579ecdb 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c @@ -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? */ diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c index 92084617d..9d0b825a3 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c @@ -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 diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c index 4c4bee560..b81841dcf 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c @@ -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" diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c index be18242a8..0b7e0dc23 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c @@ -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 diff --git a/FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/RTOSDemo.ewp b/FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/RTOSDemo.ewp index 6860b54ed..654b3b930 100644 --- a/FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/RTOSDemo.ewp +++ b/FreeRTOS/Demo/CORTEX_A5_SAMA5D2x_Xplained_IAR/RTOSDemo.ewp @@ -11,7 +11,7 @@ General 3 - 29 + 30 1 1 + @@ -620,6 +624,7 @@ @@ -1038,7 +1042,7 @@ General 3 - 29 + 30 1 1 + @@ -1644,6 +1652,7 @@ AUserIncludes $PROJ_DIR$\..\..\..\libraries $PROJ_DIR$/. + $PROJ_DIR$\..\..\Source\portable\IAR\ARM_CA5_No_GIC