]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
Sync FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP with the version in GitHub at (23665258ca...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-TCP / FreeRTOS_UDP_IP.c
index 3595bbd8188677e9c2379d8201a30527df60a287..c8de69790f469edec6043da26c6e8926824fb5e9 100644 (file)
@@ -1,58 +1,26 @@
 /*\r
- * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd.\r
- * Authors include Hein Tibosch and Richard Barry\r
+ * FreeRTOS+TCP V2.2.0\r
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
  *\r
- *******************************************************************************\r
- ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***\r
- ***                                                                         ***\r
- ***                                                                         ***\r
- ***   FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP     ***\r
- ***   demos have a dependency on FreeRTOS+FAT, which is only in the Labs    ***\r
- ***   download):                                                            ***\r
- ***                                                                         ***\r
- ***   FreeRTOS+TCP is functional and has been used in commercial products   ***\r
- ***   for some time.  Be aware however that we are still refining its       ***\r
- ***   design, the source code does not yet quite conform to the strict      ***\r
- ***   coding and style standards mandated by Real Time Engineers ltd., and  ***\r
- ***   the documentation and testing is not necessarily complete.            ***\r
- ***                                                                         ***\r
- ***   PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE    ***\r
- ***   URL: http://www.FreeRTOS.org/contact  Active early adopters may, at   ***\r
- ***   the sole discretion of Real Time Engineers Ltd., be offered versions  ***\r
- ***   under a license other than that described below.                      ***\r
- ***                                                                         ***\r
- ***                                                                         ***\r
- ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***\r
- *******************************************************************************\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
  *\r
- * FreeRTOS+TCP can be used under two different free open source licenses.  The\r
- * license that applies is dependent on the processor on which FreeRTOS+TCP is\r
- * executed, as follows:\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
  *\r
- * If FreeRTOS+TCP is executed on one of the processors listed under the Special\r
- * License Arrangements heading of the FreeRTOS+TCP license information web\r
- * page, then it can be used under the terms of the FreeRTOS Open Source\r
- * License.  If FreeRTOS+TCP is used on any other processor, then it can be used\r
- * under the terms of the GNU General Public License V2.  Links to the relevant\r
- * licenses follow:\r
- *\r
- * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license\r
- * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license\r
- * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt\r
- *\r
- * FreeRTOS+TCP is distributed in the hope that it will be useful.  You cannot\r
- * use FreeRTOS+TCP unless you agree that you use the software 'as is'.\r
- * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied\r
- * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR\r
- * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they\r
- * implied, expressed, or statutory.\r
- *\r
- * 1 tab == 4 spaces!\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
  *\r
+ * http://aws.amazon.com/freertos\r
  * http://www.FreeRTOS.org\r
- * http://www.FreeRTOS.org/plus\r
- * http://www.FreeRTOS.org/labs\r
- *\r
  */\r
 \r
 /* Standard includes. */\r
@@ -110,10 +78,22 @@ UDPPacket_t *pxUDPPacket;
 IPHeader_t *pxIPHeader;\r
 eARPLookupResult_t eReturned;\r
 uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;\r
+size_t uxPayloadSize;\r
 \r
        /* Map the UDP packet onto the start of the frame. */\r
        pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;\r
 \r
+#if ipconfigSUPPORT_OUTGOING_PINGS == 1\r
+       if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )\r
+       {\r
+               uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( ICMPPacket_t );\r
+       }\r
+       else\r
+#endif\r
+       {\r
+               uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );\r
+       }\r
+\r
        /* Determine the ARP cache status for the requested IP address. */\r
        eReturned = eARPGetCacheEntry( &( ulIPAddress ), &( pxUDPPacket->xEthernetHeader.xDestinationAddress ) );\r
 \r
@@ -141,7 +121,7 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
 \r
                                pxUDPHeader->usDestinationPort = pxNetworkBuffer->usPort;\r
                                pxUDPHeader->usSourcePort = pxNetworkBuffer->usBoundPort;\r
-                               pxUDPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( UDPHeader_t ) );\r
+                               pxUDPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( UDPHeader_t ) );\r
                                pxUDPHeader->usLength = FreeRTOS_htons( pxUDPHeader->usLength );\r
                                pxUDPHeader->usChecksum = 0u;\r
                        }\r
@@ -160,31 +140,31 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
                        and\r
                                xIPHeader.usHeaderChecksum\r
                        */\r
-\r
                        /* Save options now, as they will be overwritten by memcpy */\r
                        #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )\r
-                       {\r
                                ucSocketOptions = pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ];\r
-                       }\r
                        #endif\r
-\r
-                       memcpy( ( void *) &( pxUDPPacket->xEthernetHeader.xSourceAddress ), ( void * ) xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );\r
+                       /*\r
+                        * Offset the memcpy by the size of a MAC address to start at the packet's\r
+                        * Ethernet header 'source' MAC address; the preceding 'destination' should not be altered.\r
+                        */\r
+                       char *pxUdpSrcAddrOffset = ( char *) pxUDPPacket + sizeof( MACAddress_t );\r
+                       memcpy( pxUdpSrcAddrOffset, xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );\r
 \r
                #if ipconfigSUPPORT_OUTGOING_PINGS == 1\r
                        if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )\r
                        {\r
                                pxIPHeader->ucProtocol = ipPROTOCOL_ICMP;\r
-                               pxIPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( IPHeader_t ) );\r
+                               pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( ICMPHeader_t ) );\r
                        }\r
                        else\r
                #endif /* ipconfigSUPPORT_OUTGOING_PINGS */\r
                        {\r
-                               pxIPHeader->usLength = ( uint16_t ) ( pxNetworkBuffer->xDataLength + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );\r
+                               pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );\r
                        }\r
 \r
-                       /* The total transmit size adds on the Ethernet header. */\r
-                       pxNetworkBuffer->xDataLength = pxIPHeader->usLength + sizeof( EthernetHeader_t );\r
                        pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );\r
+                       /* HT:endian: changed back to network endian */\r
                        pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;\r
 \r
                        #if( ipconfigUSE_LLMNR == 1 )\r
@@ -206,7 +186,7 @@ uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
 \r
                                if( ( ucSocketOptions & ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT ) != 0u )\r
                                {\r
-                                       usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pdTRUE );\r
+                                       usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );\r
                                }\r
                                else\r
                                {\r
@@ -270,9 +250,13 @@ BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer
 {\r
 BaseType_t xReturn = pdPASS;\r
 FreeRTOS_Socket_t *pxSocket;\r
+configASSERT(pxNetworkBuffer);\r
+configASSERT(pxNetworkBuffer->pucEthernetBuffer);\r
+\r
 \r
 UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;\r
 \r
+       /* Caller must check for minimum packet size. */\r
        pxSocket = pxUDPSocketLookup( usPort );\r
 \r
        if( pxSocket )\r
@@ -296,10 +280,11 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
                                destinationAddress.sin_port = usPort;\r
                                destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;\r
 \r
-                               if( xHandler( ( Socket_t * ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,\r
-                                       &xSourceAddress, &destinationAddress ) != pdFALSE )\r
+                               /* The value of 'xDataLength' was proven to be at least the size of a UDP packet in prvProcessIPPacket(). */\r
+                               if( xHandler( ( Socket_t ) pxSocket, ( void* ) pcData, ( size_t ) ( pxNetworkBuffer->xDataLength - ipUDP_PAYLOAD_OFFSET_IPv4 ),\r
+                                       &xSourceAddress, &destinationAddress ) )\r
                                {\r
-                                       xReturn = pdFAIL; /* xHandler has consumed the data, do not add it to .xWaitingPacketsList'. */\r
+                                       xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */\r
                                }\r
                        }\r
                }\r
@@ -376,7 +361,7 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
                /* There is no socket listening to the target port, but still it might\r
                be for this node. */\r
 \r
-               #if( ipconfigUSE_DNS == 1 )\r
+               #if( ipconfigUSE_DNS == 1 ) && ( ipconfigDNS_USE_CALLBACKS == 1 )\r
                        /* A DNS reply, check for the source port.  Although the DNS client\r
                        does open a UDP socket to send a messages, this socket will be\r
                        closed after a short timeout.  Messages that come late (after the\r
@@ -390,7 +375,7 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
                #endif\r
 \r
                #if( ipconfigUSE_LLMNR == 1 )\r
-                       /* A LLMNR request, check for the destination port. */\r
+                       /* a LLMNR request, check for the destination port. */\r
                        if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||\r
                                ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) )\r
                        {\r