1 /*
2 * FreeRTOS+TCP <DEVELOPMENT BRANCH>
3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 * the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * http://aws.amazon.com/freertos
25 * http://www.FreeRTOS.org
26 */
27
28 /* Include Unity header */
29 #include "unity.h"
30
31 /* Include standard libraries */
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdint.h>
35
36 #include "catch_assert.h"
37
38 #include "FreeRTOSIPConfig.h"
39
40 #include "FreeRTOS_IP.h"
41 #include "FreeRTOS_IPv6.h"
42
43 /* =========================== EXTERN VARIABLES =========================== */
44
45 /* The basic length for one IPv6 extension headers. */
46 #define TEST_IPv6_EXTESION_HEADER_LENGTH ( 8U )
47
48 /* The default length ofIPv6 extension headers in unit test. */
49 #define TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH ( 7U * TEST_IPv6_EXTESION_HEADER_LENGTH )
50
51 /* First IPv6 address is 2001:1234:5678::5 */
52 const IPv6_Address_t xIPAddressFive = { 0x20, 0x01, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05 };
53
54 /* Second IPv6 address is 2001:1234:5678::10 */
55 const IPv6_Address_t xIPAddressTen = { 0x20, 0x01, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 };
56
57 /* MAC Address for endpoint. */
58 const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] = { 0xab, 0xcd, 0xef, 0x11, 0x22, 0x33 };
59
60 /* ======================== Stub Callback Functions ========================= */
61
prvInitializeEndpoint()62 static NetworkEndPoint_t * prvInitializeEndpoint()
63 {
64 static NetworkEndPoint_t xEndpoint;
65
66 memset( &xEndpoint, 0, sizeof( xEndpoint ) );
67 xEndpoint.bits.bIPv6 = 1U;
68 memcpy( xEndpoint.ipv6_settings.xIPAddress.ucBytes, xIPAddressFive.ucBytes, ipSIZE_OF_IPv6_ADDRESS );
69
70 return &xEndpoint;
71 }
72
prvInitializeNetworkDescriptor()73 static NetworkBufferDescriptor_t * prvInitializeNetworkDescriptor()
74 {
75 static NetworkBufferDescriptor_t xNetworkBuffer;
76 static uint8_t pcNetworkBuffer[ sizeof( TCPPacket_IPv6_t ) ];
77 TCPPacket_IPv6_t * pxTCPPacket = ( TCPPacket_IPv6_t * ) pcNetworkBuffer;
78
79 /* Initialize network buffer descriptor. */
80 memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
81 xNetworkBuffer.pxEndPoint = prvInitializeEndpoint();
82 xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) pxTCPPacket;
83 xNetworkBuffer.xDataLength = sizeof( TCPPacket_IPv6_t );
84
85 /* Initialize network buffer. */
86 memset( pcNetworkBuffer, 0, sizeof( pcNetworkBuffer ) );
87 /* Ethernet part. */
88 memcpy( pxTCPPacket->xEthernetHeader.xDestinationAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) );
89 memcpy( pxTCPPacket->xEthernetHeader.xSourceAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) );
90 pxTCPPacket->xEthernetHeader.usFrameType = ipIPv6_FRAME_TYPE;
91 /* IP part. */
92 memcpy( pxTCPPacket->xIPHeader.xSourceAddress.ucBytes, xIPAddressTen.ucBytes, sizeof( IPv6_Address_t ) );
93 memcpy( pxTCPPacket->xIPHeader.xDestinationAddress.ucBytes, xIPAddressFive.ucBytes, sizeof( IPv6_Address_t ) );
94
95 return &xNetworkBuffer;
96 }
97
98 /*
99 * Prepare a packet have extension with following order. Check if eHandleIPv6ExtensionHeaders determines to process it.
100 * - ipIPv6_EXT_HEADER_HOP_BY_HOP
101 * - ipIPv6_EXT_HEADER_ROUTING_HEADER
102 * - ipIPv6_EXT_HEADER_FRAGMENT_HEADER
103 * - ipIPv6_EXT_HEADER_SECURE_PAYLOAD
104 * - ipIPv6_EXT_HEADER_AUTHEN_HEADER
105 * - ipIPv6_EXT_HEADER_DESTINATION_OPTIONS
106 * - ipIPv6_EXT_HEADER_MOBILITY_HEADER
107 */
prvInitializeNetworkDescriptorWithExtensionHeader(uint8_t ucProtocol)108 static NetworkBufferDescriptor_t * prvInitializeNetworkDescriptorWithExtensionHeader( uint8_t ucProtocol )
109 {
110 static NetworkBufferDescriptor_t xNetworkBuffer;
111 /* Ethernet header + IPv6 header + Maximum protocol header + IPv6 Extension Headers + 1 payload */
112 static uint8_t pcNetworkBuffer[ sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ) + TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH + sizeof( ICMPHeader_IPv6_t ) + 1U ];
113 EthernetHeader_t * pxEthHeader = ( EthernetHeader_t * ) pcNetworkBuffer;
114 IPHeader_IPv6_t * pxIPv6Header = ( IPHeader_IPv6_t * ) &( pcNetworkBuffer[ sizeof( EthernetHeader_t ) ] );
115 uint8_t * pxIPv6ExtHeader = ( uint8_t * ) &( pcNetworkBuffer[ sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ) ] );
116 size_t uxIndex = sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t );
117 uint8_t ucProtocolHeaderSize;
118
119 if( ucProtocol == ipPROTOCOL_TCP )
120 {
121 ucProtocolHeaderSize = sizeof( TCPHeader_t );
122 }
123 else if( ucProtocol == ipPROTOCOL_UDP )
124 {
125 ucProtocolHeaderSize = sizeof( UDPHeader_t );
126 }
127 else if( ucProtocol == ipPROTOCOL_ICMP_IPv6 )
128 {
129 ucProtocolHeaderSize = sizeof( ICMPHeader_IPv6_t );
130 }
131 else
132 {
133 TEST_ASSERT_TRUE( false );
134 }
135
136 /* Initialize network buffer descriptor. */
137 memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
138 xNetworkBuffer.pxEndPoint = prvInitializeEndpoint();
139 xNetworkBuffer.pucEthernetBuffer = ( uint8_t * ) pcNetworkBuffer;
140 xNetworkBuffer.xDataLength = sizeof( EthernetHeader_t ) + sizeof( IPHeader_IPv6_t ) + TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH + ucProtocolHeaderSize + 1U;
141
142 /* Initialize network buffer. */
143 memset( pcNetworkBuffer, 0, sizeof( pcNetworkBuffer ) );
144 /* Ethernet part. */
145 memcpy( pxEthHeader->xDestinationAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) );
146 memcpy( pxEthHeader->xSourceAddress.ucBytes, ucMACAddress, sizeof( ucMACAddress ) );
147 pxEthHeader->usFrameType = ipIPv6_FRAME_TYPE;
148 /* IP part. */
149 memcpy( pxIPv6Header->xSourceAddress.ucBytes, xIPAddressTen.ucBytes, sizeof( IPv6_Address_t ) );
150 memcpy( pxIPv6Header->xDestinationAddress.ucBytes, xIPAddressFive.ucBytes, sizeof( IPv6_Address_t ) );
151 pxIPv6Header->usPayloadLength = FreeRTOS_htons( TEST_IPv6_DEFAULT_EXTESION_HEADERS_LENGTH + ucProtocolHeaderSize + 1U ); /* Extension header length + protocol header + payload */
152 pxIPv6Header->ucNextHeader = ipIPv6_EXT_HEADER_HOP_BY_HOP;
153 /* Append extension headers */
154 pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_ROUTING_HEADER;
155 pcNetworkBuffer[ uxIndex + 1 ] = 0;
156 uxIndex += 8;
157 pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_FRAGMENT_HEADER;
158 pcNetworkBuffer[ uxIndex + 1 ] = 0;
159 uxIndex += 8;
160 pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_SECURE_PAYLOAD;
161 pcNetworkBuffer[ uxIndex + 1 ] = 0;
162 uxIndex += 8;
163 pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_AUTHEN_HEADER;
164 pcNetworkBuffer[ uxIndex + 1 ] = 0;
165 uxIndex += 8;
166 pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_DESTINATION_OPTIONS;
167 pcNetworkBuffer[ uxIndex + 1 ] = 0;
168 uxIndex += 8;
169 pcNetworkBuffer[ uxIndex ] = ipIPv6_EXT_HEADER_MOBILITY_HEADER;
170 pcNetworkBuffer[ uxIndex + 1 ] = 0;
171 uxIndex += 8;
172 pcNetworkBuffer[ uxIndex ] = ucProtocol;
173 pcNetworkBuffer[ uxIndex + 1 ] = 0;
174 uxIndex += 8;
175
176 return &xNetworkBuffer;
177 }
178