/* * FreeRTOS+TCP * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * SPDX-License-Identifier: MIT * * 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 Unity header */ #include "unity.h" /* Include standard libraries */ #include #include #include #include "catch_assert.h" #include "FreeRTOSIPConfig.h" #include "FreeRTOS_IP.h" #include "FreeRTOS_IPv6.h" /* =========================== EXTERN VARIABLES =========================== */ /* The basic length for one IPv6 extension headers. */ #define TEST_IPv6_EXTESION_HEADER_LENGTH ( 8U ) /* The default length ofIPv6 extension headers in unit test. */ #define TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH ( 7U * TEST_IPv6_EXTESION_HEADER_LENGTH ) /* First IPv6 address is 2001:1234:5678::5 */ const IPv6_Address_t xIPAddressFive = { 0x20, 0x01, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05 }; /* Second IPv6 address is 2001:1234:5678::10 */ const IPv6_Address_t xIPAddressTen = { 0x20, 0x01, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; /* MAC Address for endpoint. */ const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] = { 0xab, 0xcd, 0xef, 0x11, 0x22, 0x33 }; /* ======================== Stub Callback Functions ========================= */ static NetworkEndPoint_t * prvInitializeEndpoint() { static NetworkEndPoint_t xEndpoint; memset( &xEndpoint, 0, sizeof( xEndpoint ) ); xEndpoint.bits.bIPv6 = 1U; memcpy( xEndpoint.ipv6_settings.xIPAddress.ucBytes, xIPAddressFive.ucBytes, ipSIZE_OF_IPv6_ADDRESS ); return &xEndpoint; } static NetworkBufferDescriptor_t * prvInitializeNetworkDescriptor() { static NetworkBufferDescriptor_t xNetworkBuffer; static uint8_t pcNetworkBuffer[ sizeof( TCPPacket_IPv6_t ) ]; TCPPacket_IPv6_t * pxTCPPacket = ( TCPPacket_IPv6_t * ) pcNetworkBuffer; /* Initialize network buffer descriptor. */ memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) ); xNetworkBuffer.pxEndPoint = prvInitializeEndpoint(); xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) pxTCPPacket; xNetworkBuffer.xDataLength = sizeof( TCPPacket_IPv6_t ); /* Initialize network buffer. */ memset( pcNetworkBuffer, 0, sizeof( pcNetworkBuffer ) ); /* Ethernet part. */ memcpy( pxTCPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) ); memcpy( pxTCPPacket->xEthernetHeader.xSourceAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) ); pxTCPPacket->xEthernetHeader.usFrameType = ipIPv6_FRAME_TYPE; /* IP part. */ memcpy( pxTCPPacket->xIPHeader.xSourceAddress.ucBytes, xIPAddressTen.ucBytes, sizeof( IPv6_Address_t ) ); memcpy( pxTCPPacket->xIPHeader.xDestinationAddress.ucBytes, xIPAddressFive.ucBytes, sizeof( IPv6_Address_t ) ); return &xNetworkBuffer; } /* * Prepare a packet have extension with following order. Check if eHandleIPv6ExtensionHeaders determines to process it. * - ipIPv6_EXT_HEADER_HOP_BY_HOP * - ipIPv6_EXT_HEADER_ROUTING_HEADER * - ipIPv6_EXT_HEADER_FRAGMENT_HEADER * - ipIPv6_EXT_HEADER_SECURE_PAYLOAD * - ipIPv6_EXT_HEADER_AUTHEN_HEADER * - ipIPv6_EXT_HEADER_DESTINATION_OPTIONS * - ipIPv6_EXT_HEADER_MOBILITY_HEADER */ static NetworkBufferDescriptor_t * prvInitializeNetworkDescriptorWithExtensionHeader( uint8_t ucProtocol ) { static NetworkBufferDescriptor_t xNetworkBuffer; /* Ethernet header + IPv6 header + Maximum protocol header + IPv6 Extension Headers + 1 payload */ static uint8_t pcNetworkBuffer[ sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ) + TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH + sizeof( ICMPHeader_IPv6_t ) + 1U ]; EthernetHeader_t * pxEthHeader = ( EthernetHeader_t * ) pcNetworkBuffer; IPHeader_IPv6_t * pxIPv6Header = ( IPHeader_IPv6_t * ) &( pcNetworkBuffer[ sizeof( EthernetHeader_t ) ] ); uint8_t * pxIPv6ExtHeader = ( uint8_t * ) &( pcNetworkBuffer[ sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ) ] ); size_t uxIndex = sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ); uint8_t ucProtocolHeaderSize; if( ucProtocol == ipPROTOCOL_TCP ) { ucProtocolHeaderSize = sizeof( TCPHeader_t ); } else if( ucProtocol == ipPROTOCOL_UDP ) { ucProtocolHeaderSize = sizeof( UDPHeader_t ); } else if( ucProtocol == ipPROTOCOL_ICMP_IPv6 ) { ucProtocolHeaderSize = sizeof( ICMPHeader_IPv6_t ); } else { TEST_ASSERT_TRUE( false ); } /* Initialize network buffer descriptor. */ memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) ); xNetworkBuffer.pxEndPoint = prvInitializeEndpoint(); xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) pcNetworkBuffer; xNetworkBuffer.xDataLength = sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ) + TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH + ucProtocolHeaderSize + 1U; /* Initialize network buffer. */ memset( pcNetworkBuffer, 0, sizeof( pcNetworkBuffer ) ); /* Ethernet part. */ memcpy( pxEthHeader->xDestinationAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) ); memcpy( pxEthHeader->xSourceAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) ); pxEthHeader->usFrameType = ipIPv6_FRAME_TYPE; /* IP part. */ memcpy( pxIPv6Header->xSourceAddress.ucBytes, xIPAddressTen.ucBytes, sizeof( IPv6_Address_t ) ); memcpy( pxIPv6Header->xDestinationAddress.ucBytes, xIPAddressFive.ucBytes, sizeof( IPv6_Address_t ) ); pxIPv6Header->usPayloadLength = FreeRTOS_htons( TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH + ucProtocolHeaderSize + 1U ); /* Extension header length + protocol header + payload */ pxIPv6Header->ucNextHeader = ipIPv6_EXT_HEADER_HOP_BY_HOP; /* Append extension headers */ pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_ROUTING_HEADER; pcNetworkBuffer[ uxIndex + 1 ] = 0; uxIndex += 8; pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_FRAGMENT_HEADER; pcNetworkBuffer[ uxIndex + 1 ] = 0; uxIndex += 8; pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_SECURE_PAYLOAD; pcNetworkBuffer[ uxIndex + 1 ] = 0; uxIndex += 8; pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_AUTHEN_HEADER; pcNetworkBuffer[ uxIndex + 1 ] = 0; uxIndex += 8; pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_DESTINATION_OPTIONS; pcNetworkBuffer[ uxIndex + 1 ] = 0; uxIndex += 8; pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_MOBILITY_HEADER; pcNetworkBuffer[ uxIndex + 1 ] = 0; uxIndex += 8; pcNetworkBuffer[ uxIndex ] = ucProtocol; pcNetworkBuffer[ uxIndex + 1 ] = 0; uxIndex += 8; return &xNetworkBuffer; }