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_IPV4_PRIVATE_H
29 #define FREERTOS_IPV4_PRIVATE_H
30 
31 #include "FreeRTOS_IP_Private.h"
32 
33 /* *INDENT-OFF* */
34 #ifdef __cplusplus
35     extern "C" {
36 #endif
37 /* *INDENT-ON* */
38 
39 /* The maximum UDP payload length. */
40 #define ipMAX_UDP_PAYLOAD_LENGTH        ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER ) - ipSIZE_OF_UDP_HEADER )
41 
42 #define TCP_PACKET_SIZE                 ( sizeof( TCPPacket_t ) )
43 
44 /* The offset into an IP packet into which the IP data (payload) starts. */
45 #define ipIP_PAYLOAD_OFFSET             ( sizeof( IPPacket_t ) )
46 /* The offset into a UDP packet at which the UDP data (payload) starts. */
47 #define ipUDP_PAYLOAD_OFFSET_IPv4       ( sizeof( UDPPacket_t ) )
48 /* The value of 'ipUDP_PAYLOAD_IP_TYPE_OFFSET' is 8 + 40 = 48 bytes. */
49 #define ipUDP_PAYLOAD_IP_TYPE_OFFSET    ( sizeof( UDPHeader_t ) + sizeof( IPHeader_IPv6_t ) )
50 
51 /* ipIP_TYPE_OFFSET is involved in some sorcery. pxUDPPayloadBuffer_to_NetworkBuffer() must be able to convert
52  * a payload pointer ( like for example a pointer to the DNS payload of a packet ) back to a NetworkBufferDescriptor_t.
53  * This must work for both IPv4 and IPv6 packets. The pointer conversion is done by subtracting a constant from the payload pointer.
54  * For IPv6, this magic number is ( sizeof( UDPHeader_t ) + sizeof( IPHeader_IPv6_t ) ) which equals 48 bytes.
55  * If however we use that same constant for an IPv4 packet, we end up somewhere in front of the Ethernet header.
56  * In order to accommodate that, the Ethernet frame buffer gets allocated a bit larger than needed.
57  * For IPv4 frames, prvProcessIPPacket() stores the version header field at a negative offset, a few bytes before the start
58  * of the Ethernet header. That IPv4 version field MUST be stored the same distance from the payload as in IPv6.
59  * ipIP_TYPE_OFFSET must be equal to: sizeof( UDPHeader_t ) + sizeof( IPHeader_IPv6_t ) - ( sizeof( UDPPacket_t )
60  * In most situations, ipIP_TYPE_OFFSET will end up being equal to 6. If the Ethernet header is enlarged to include VLAN
61  * tag support, ipIP_TYPE_OFFSET will shrink to 2. With the current design, the Ethernet header cannot be expanded to contain
62  * more than one VLAN tag or ipIP_TYPE_OFFSET will become less than zero. ipIP_TYPE_OFFSET should never be allowed to be <= 0
63  * or storing of the IPv4 version byte will overwrite the Ethernet header of the frame.
64  */
65 #define ipIP_TYPE_OFFSET                ( ( int32_t ) sizeof( UDPHeader_t ) + ( int32_t ) sizeof( IPHeader_IPv6_t ) - ( int32_t ) sizeof( UDPPacket_t ) )
66 
67 #include "pack_struct_start.h"
68 struct xIP_HEADER
69 {
70     uint8_t ucVersionHeaderLength;        /**< The version field + internet header length 0 + 1 =  1 */
71     uint8_t ucDifferentiatedServicesCode; /**< Differentiated services code point + ECN   1 + 1 =  2 */
72     uint16_t usLength;                    /**< Entire Packet size, ex. Ethernet header.   2 + 2 =  4 */
73     uint16_t usIdentification;            /**< Identification field                       4 + 2 =  6 */
74     uint16_t usFragmentOffset;            /**< Fragment flags and fragment offset         6 + 2 =  8 */
75     uint8_t ucTimeToLive;                 /**< Time to live field                         8 + 1 =  9 */
76     uint8_t ucProtocol;                   /**< Protocol used in the IP-datagram           9 + 1 = 10 */
77     uint16_t usHeaderChecksum;            /**< Checksum of the IP-header                 10 + 2 = 12 */
78     uint32_t ulSourceIPAddress;           /**< IP address of the source                  12 + 4 = 16 */
79     uint32_t ulDestinationIPAddress;      /**< IP address of the destination             16 + 4 = 20 */
80 }
81 #include "pack_struct_end.h"
82 typedef struct xIP_HEADER IPHeader_t;
83 
84 /*-----------------------------------------------------------*/
85 /* Nested protocol packets.                                  */
86 /*-----------------------------------------------------------*/
87 
88 #include "pack_struct_start.h"
89 struct xIP_PACKET
90 {
91     EthernetHeader_t xEthernetHeader;
92     IPHeader_t xIPHeader;
93 }
94 #include "pack_struct_end.h"
95 typedef struct xIP_PACKET IPPacket_t;
96 
97 #include "pack_struct_start.h"
98 struct xICMP_PACKET
99 {
100     EthernetHeader_t xEthernetHeader; /**< The Ethernet header of an ICMP packet. */
101     IPHeader_t xIPHeader;             /**< The IP header of an ICMP packet. */
102     ICMPHeader_t xICMPHeader;         /**< The ICMP header of an ICMP packet. */
103 }
104 #include "pack_struct_end.h"
105 typedef struct xICMP_PACKET ICMPPacket_t;
106 
107 
108 #include "pack_struct_start.h"
109 struct xUDP_PACKET
110 {
111     EthernetHeader_t xEthernetHeader; /**< UDP-Packet ethernet header  0 + 14 = 14 */
112     IPHeader_t xIPHeader;             /**< UDP-Packet IP header        14 + 20 = 34 */
113     UDPHeader_t xUDPHeader;           /**< UDP-Packet UDP header       34 +  8 = 42 */
114 }
115 #include "pack_struct_end.h"
116 typedef struct xUDP_PACKET UDPPacket_t;
117 
118 #include "pack_struct_start.h"
119 struct xTCP_PACKET
120 {
121     EthernetHeader_t xEthernetHeader; /**< The ethernet header  0 + 14 = 14 */
122     IPHeader_t xIPHeader;             /**< The IP header        14 + 20 = 34 */
123     TCPHeader_t xTCPHeader;           /**< The TCP header       34 + 32 = 66 */
124 }
125 #include "pack_struct_end.h"
126 typedef struct xTCP_PACKET TCPPacket_t;
127 
128 /* *INDENT-OFF* */
129 #ifdef __cplusplus
130     } /* extern "C" */
131 #endif
132 /* *INDENT-ON* */
133 
134 #endif /* FREERTOS_IP_PRIVATE_H */
135