xref: /FreeRTOS-Plus-TCP-v4.0.0/test/unit-test/FreeRTOS_IPv6/FreeRTOS_IPv6_stubs.c (revision 2d3f4daa567ffe71aeda2e0f6d0bc02850db0627)
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