xref: /FreeRTOS-Plus-TCP-v4.0.0/source/include/FreeRTOS_IPv6_Private.h (revision 1c7623da4e2b3a086cad5852a9ce663ab9e17c29)
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  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  */
27 
28 #ifndef FREERTOS_IPV6_PRIVATE_H
29 #define FREERTOS_IPV6_PRIVATE_H
30 
31 /* Application level configuration options. */
32 #include "FreeRTOSIPConfig.h"
33 #include "FreeRTOSIPConfigDefaults.h"
34 #include "FreeRTOS_IP_Common.h"
35 #include "FreeRTOS_Sockets.h"
36 #include "IPTraceMacroDefaults.h"
37 #include "FreeRTOS_Stream_Buffer.h"
38 #if ( ipconfigUSE_TCP == 1 )
39     #include "FreeRTOS_TCP_WIN.h"
40     #include "FreeRTOS_TCP_IP.h"
41 #endif
42 
43 #include "semphr.h"
44 
45 #include "event_groups.h"
46 
47 /* *INDENT-OFF* */
48 #ifdef __cplusplus
49     extern "C" {
50 #endif
51 /* *INDENT-ON* */
52 
53 /* MISRA Ref 20.5.1 [Use of undef] */
54 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-2051 */
55 /* coverity[misra_c_2012_rule_20_5_violation] */
56 #undef TCP_PACKET_SIZE
57 #define TCP_PACKET_SIZE          ( sizeof( TCPPacket_IPv6_t ) )
58 
59 /* The offset into an IP packet into which the IP data (payload) starts. */
60 #define ipIPv6_PAYLOAD_OFFSET    ( sizeof( IPPacket_IPv6_t ) )
61 /* MISRA Ref 20.5.1 [Use of undef] */
62 /* More details at: https://github.com/FreeRTOS/FreeRTOS-Plus-TCP/blob/main/MISRA.md#rule-2051 */
63 /* coverity[misra_c_2012_rule_20_5_violation] */
64 /* The maximum UDP payload length. */
65 #undef ipMAX_UDP_PAYLOAD_LENGTH
66 #define ipMAX_UDP_PAYLOAD_LENGTH     ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv6_HEADER ) - ipSIZE_OF_UDP_HEADER )
67 /* The offset into a UDP packet at which the UDP data (payload) starts. */
68 #define ipUDP_PAYLOAD_OFFSET_IPv6    ( sizeof( UDPPacket_IPv6_t ) )
69 
70 #if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
71 
72     #define ipIPv6_FRAME_TYPE    ( 0xDD86U )               /* Ethernet frame types. */
73 
74 #else /* if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) */
75 
76     #define ipIPv6_FRAME_TYPE    ( 0x86DDU )               /* Ethernet frame types. */
77 
78 #endif /* ipconfigBYTE_ORDER */
79 
80 /* In this library, there is often a cast from a character pointer
81  * to a pointer to a struct.
82  * In order to suppress MISRA warnings, do the cast within a macro,
83  * which can be exempt from warnings:
84  *
85  * 3 required by MISRA:
86  * -emacro(740,ipPOINTER_CAST)    // 750:  Unusual pointer cast (incompatible indirect types) [MISRA 2012 Rule 1.3, required])
87  * -emacro(9005,ipPOINTER_CAST)   // 9005: attempt to cast away const/volatile from a pointer or reference [MISRA 2012 Rule 11.8, required]
88  * -emacro(9087,ipPOINTER_CAST)   // 9087: cast performed between a pointer to object type and a pointer to a different object type [MISRA 2012 Rule 11.3, required]
89  *
90  * 2 advisory by MISRA:
91  * -emacro(9079,ipPOINTER_CAST)   // 9079: conversion from pointer to void to pointer to other type [MISRA 2012 Rule 11.5, advisory])
92  * --emacro((826),ipPOINTER_CAST) // 826:  Suspicious pointer-to-pointer conversion (area too small)
93  *
94  * The MISRA warnings can safely be suppressed because all casts are planned with care.
95  */
96 
97 #define ipPOINTER_CAST( TYPE, pointer )    ( ( TYPE ) ( pointer ) )
98 
99 /* Sequence and ACK numbers are essentially unsigned (uint32_t). But when
100  * a distance is calculated, it is useful to use signed numbers:
101  * int32_t lDistance = ( int32_t ) ( ulSeq1 - ulSeq2 );
102  *
103  * 1 required by MISRA:
104  * -emacro(9033,ipNUMERIC_CAST) // 9033: Impermissible cast of composite expression (different essential type categories) [MISRA 2012 Rule 10.8, required])
105  *
106  * 1 advisory by MISRA:
107  * -emacro(9030,ipNUMERIC_CAST) // 9030: Impermissible cast; cannot cast from 'essentially Boolean' to 'essentially signed' [MISRA 2012 Rule 10.5, advisory])
108  */
109 
110 #define ipNUMERIC_CAST( TYPE, expression )    ( ( TYPE ) ( expression ) )
111 
112 
113 /** @brief The macros vSetField16() and vSetField32() will write either a short or a 32-bit
114  * value into an array of bytes. They will be stored big-endian.
115  * The helper functions do the actual work.
116  */
117 
118 /*extern void vSetField16helper( uint8_t * pucBase,
119  *                             size_t uxOffset,
120  *                             uint16_t usValue );
121  #define vSetField16( pucBase, xType, xField, usValue ) \
122  *  vSetField16helper( pucBase, offsetof( xType, xField ), usValue )
123  *
124  * extern void vSetField32helper( uint8_t * pucBase,
125  *                             size_t uxOffset,
126  *                             uint32_t ulValue );
127  #define vSetField32( pucBase, xType, xField, ulValue ) \
128  *  vSetField32helper( pucBase, offsetof( xType, xField ), ulValue )
129  */
130 
131 /* As FreeRTOS_Routing is included later, use forward declarations
132  * of the two structs. */
133 struct xNetworkEndPoint;
134 struct xNetworkInterface;
135 
136 #include "pack_struct_start.h"
137 struct xIP_HEADER_IPv6
138 {
139     uint8_t ucVersionTrafficClass;      /**< The version field.                      0 +  1 =  1 */
140     uint8_t ucTrafficClassFlow;         /**< Traffic class and flow.                 1 +  1 =  2 */
141     uint16_t usFlowLabel;               /**< Flow label.                             2 +  2 =  4 */
142     uint16_t usPayloadLength;           /**< Number of bytes after the IPv6 header.  4 +  2 =  6 */
143     uint8_t ucNextHeader;               /**< Next header: TCP, UDP, or ICMP.         6 +  1 =  7 */
144     uint8_t ucHopLimit;                 /**< Replaces the time to live from IPv4.    7 +  1 =  8 */
145     IPv6_Address_t xSourceAddress;      /**< The IPv6 address of the sender.         8 + 16 = 24 */
146     IPv6_Address_t xDestinationAddress; /**< The IPv6 address of the receiver.      24 + 16 = 40 */
147 }
148 #include "pack_struct_end.h"
149 typedef struct xIP_HEADER_IPv6 IPHeader_IPv6_t;
150 
151 #include "pack_struct_start.h"
152 struct xIP_EXT_HEADER_IPv6
153 {
154     uint8_t ucNextHeader;      /**< Next header: TCP, UDP, or ICMP.                                            0 +  1 =  1 */
155     uint8_t ucHeaderExtLength; /**< Length of this header in 8-octet units, not including the first 8 octets.  1 +  1 =  2 */
156 }
157 #include "pack_struct_end.h"
158 typedef struct xIP_EXT_HEADER_IPv6 IPExtHeader_IPv6_t;
159 
160 #include "pack_struct_start.h"
161 struct xICMPEcho_IPv6
162 {
163     uint8_t ucTypeOfMessage;   /**< The message type.     0 +  1 = 1 */
164     uint8_t ucTypeOfService;   /**< Type of service.      1 +  1 = 2 */
165     uint16_t usChecksum;       /**< Checksum.             2 +  2 = 4 */
166     uint16_t usIdentifier;     /**< Identifier.           4 +  2 = 6 */
167     uint16_t usSequenceNumber; /**< Sequence number.      6 +  2 = 8 */
168 }
169 #include "pack_struct_end.h"
170 typedef struct xICMPEcho_IPv6 ICMPEcho_IPv6_t;
171 
172 #include "pack_struct_start.h"
173 struct xICMPRouterSolicitation_IPv6
174 {
175     uint8_t ucTypeOfMessage; /**<  0 +  1 =  1 */
176     uint8_t ucTypeOfService; /**<  1 +  1 =  2 */
177     uint16_t usChecksum;     /**<  2 +  2 =  4 */
178     uint32_t ulReserved;     /**<  4 +  4 =  8 */
179 }
180 #include "pack_struct_end.h"
181 typedef struct xICMPRouterSolicitation_IPv6 ICMPRouterSolicitation_IPv6_t;
182 
183 #if ( ipconfigUSE_RA != 0 )
184     #include "pack_struct_start.h"
185     struct xICMPRouterAdvertisement_IPv6
186     {
187         uint8_t ucTypeOfMessage;       /*  0 +  1 =  1 */
188         uint8_t ucTypeOfService;       /*  1 +  1 =  2 */
189         uint16_t usChecksum;           /*  2 +  2 =  4 */
190         uint8_t ucHopLimit;            /*  4 +  1 =  5 */
191         uint8_t ucFlags;               /*  5 +  1 =  6 */
192         uint16_t usLifetime;           /*  6 +  2 =  8 */
193         uint16_t usReachableTime[ 2 ]; /*  8 +  4 = 12 */
194         uint16_t usRetransTime[ 2 ];   /* 12 +  4 = 16 */
195     }
196     #include "pack_struct_end.h"
197     typedef struct xICMPRouterAdvertisement_IPv6 ICMPRouterAdvertisement_IPv6_t;
198 
199     #include "pack_struct_start.h"
200     struct xICMPPrefixOption_IPv6
201     {
202         uint8_t ucType;               /*  0 +  1 =  1 */
203         uint8_t ucLength;             /*  1 +  1 =  2 */
204         uint8_t ucPrefixLength;       /*  2 +  1 =  3 */
205         uint8_t ucFlags;              /*  3 +  1 =  4 */
206         uint32_t ulValidLifeTime;     /*  4 +  4 =  8 */
207         uint32_t ulPreferredLifeTime; /*  8 +  4 = 12 */
208         uint32_t ulReserved;          /* 12 +  4 = 16 */
209         uint8_t ucPrefix[ 16 ];       /* 16 + 16 = 32 */
210     }
211     #include "pack_struct_end.h"
212     typedef struct xICMPPrefixOption_IPv6 ICMPPrefixOption_IPv6_t;
213 #endif /* ipconfigUSE_RA != 0 */
214 
215 /*-----------------------------------------------------------*/
216 /* Nested protocol packets.                                  */
217 /*-----------------------------------------------------------*/
218 
219 #include "pack_struct_start.h"
220 struct xIP_PACKET_IPv6
221 {
222     EthernetHeader_t xEthernetHeader;
223     IPHeader_IPv6_t xIPHeader;
224 }
225 #include "pack_struct_end.h"
226 typedef struct xIP_PACKET_IPv6 IPPacket_IPv6_t;
227 
228 #include "pack_struct_start.h"
229 struct xICMP_PACKET_IPv6
230 {
231     EthernetHeader_t xEthernetHeader;  /*  0 + 14 = 14 */
232     IPHeader_IPv6_t xIPHeader;         /* 14 + 40 = 54 */
233     ICMPHeader_IPv6_t xICMPHeaderIPv6; /* 54 +  8 = 62 */
234 }
235 #include "pack_struct_end.h"
236 typedef struct xICMP_PACKET_IPv6 ICMPPacket_IPv6_t;
237 
238 #include "pack_struct_start.h"
239 struct xUDP_PACKET_IPv6
240 {
241     EthernetHeader_t xEthernetHeader; /*  0 + 14 = 14 */
242     IPHeader_IPv6_t xIPHeader;        /* 14 + 40 = 54 */
243     UDPHeader_t xUDPHeader;           /* 54 +  8 = 62 */
244 }
245 #include "pack_struct_end.h"
246 typedef struct xUDP_PACKET_IPv6 UDPPacket_IPv6_t;
247 
248 #include "pack_struct_start.h"
249 struct xTCP_PACKET_IPv6
250 {
251     EthernetHeader_t xEthernetHeader; /*  0 + 14 = 14 */
252     IPHeader_IPv6_t xIPHeader;        /* 14 + 40 = 54 */
253     TCPHeader_t xTCPHeader;           /* 54 + 32 = 86 */
254 }
255 #include "pack_struct_end.h"
256 typedef struct xTCP_PACKET_IPv6 TCPPacket_IPv6_t;
257 
258 /* prvProcessICMPMessage_IPv6() is declared in FreeRTOS_routing.c
259  * It handles all ICMP messages except the PING requests. */
260 eFrameProcessingResult_t prvProcessICMPMessage_IPv6( NetworkBufferDescriptor_t * const pxNetworkBuffer );
261 
262 
263 #if ( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
264 /* prepare a string which describes a socket, just for logging. */
265     const char * prvSocketProps( FreeRTOS_Socket_t * pxSocket );
266 #endif /* ipconfigHAS_DEBUG_PRINTF || ipconfigHAS_PRINTF */
267 
268 /* *INDENT-OFF* */
269 #ifdef __cplusplus
270     } /* extern "C" */
271 #endif
272 /* *INDENT-ON* */
273 
274 #endif /* FREERTOS_IP_PRIVATE_H */
275