ipv4.h
Go to the documentation of this file.
1 /**
2  * @file ipv4.h
3  * @brief IPv4 (Internet Protocol Version 4)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 #ifndef _IPV4_H
32 #define _IPV4_H
33 
34 //Forward declaration of structures
35 struct _Ipv4Header;
36 #define Ipv4Header struct _Ipv4Header
37 
38 struct _Ipv4PseudoHeader;
39 #define Ipv4PseudoHeader struct _Ipv4PseudoHeader
40 
41 //Dependencies
42 #include <string.h>
43 #include "core/net.h"
44 #include "core/ethernet.h"
45 #include "ipv4/ipv4_frag.h"
46 
47 //IPv4 support
48 #ifndef IPV4_SUPPORT
49  #define IPV4_SUPPORT ENABLED
50 #elif (IPV4_SUPPORT != ENABLED && IPV4_SUPPORT != DISABLED)
51  #error IPV4_SUPPORT parameter is not valid
52 #endif
53 
54 //Default IPv4 time-to-live value
55 #ifndef IPV4_DEFAULT_TTL
56  #define IPV4_DEFAULT_TTL 64
57 #elif (IPV4_DEFAULT_TTL < 1)
58  #error IPV4_DEFAULT_TTL parameter is not valid
59 #endif
60 
61 //Maximum number of IPv4 addresses
62 #ifndef IPV4_ADDR_LIST_SIZE
63  #define IPV4_ADDR_LIST_SIZE 1
64 #elif (IPV4_ADDR_LIST_SIZE < 1)
65  #error IPV4_ADDR_LIST_SIZE parameter is not valid
66 #endif
67 
68 //Maximum number of DNS servers
69 #ifndef IPV4_DNS_SERVER_LIST_SIZE
70  #define IPV4_DNS_SERVER_LIST_SIZE 2
71 #elif (IPV4_DNS_SERVER_LIST_SIZE < 1)
72  #error IPV4_DNS_SERVER_LIST_SIZE parameter is not valid
73 #endif
74 
75 //Size of the IPv4 multicast filter
76 #ifndef IPV4_MULTICAST_FILTER_SIZE
77  #define IPV4_MULTICAST_FILTER_SIZE 4
78 #elif (IPV4_MULTICAST_FILTER_SIZE < 1)
79  #error IPV4_MULTICAST_FILTER_SIZE parameter is not valid
80 #endif
81 
82 //Version number for IPv4
83 #define IPV4_VERSION 4
84 //Minimum MTU
85 #define IPV4_MINIMUM_MTU 68
86 //Default MTU
87 #define IPV4_DEFAULT_MTU 576
88 //Minimum header length
89 #define IPV4_MIN_HEADER_LENGTH 20
90 //Maximum header length
91 #define IPV4_MAX_HEADER_LENGTH 60
92 
93 //Shortcut to data field
94 #define IPV4_DATA(packet) PTR_OFFSET(packet, packet->headerLength * 4)
95 
96 //Macro used for defining an IPv4 address
97 #ifdef _CPU_BIG_ENDIAN
98  #define IPV4_ADDR(a, b, c, d) (((uint32_t) (a) << 24) | ((b) << 16) | ((c) << 8) | (d))
99 #else
100  #define IPV4_ADDR(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((uint32_t) (d) << 24))
101 #endif
102 
103 //Unspecified IPv4 address
104 #define IPV4_UNSPECIFIED_ADDR IPV4_ADDR(0, 0, 0, 0)
105 //Broadcast IPV4 address
106 #define IPV4_BROADCAST_ADDR IPV4_ADDR(255, 255, 255, 255)
107 
108 //Loopback IPv4 address
109 #define IPV4_LOOPBACK_ADDR IPV4_ADDR(127, 0, 0, 1)
110 #define IPV4_LOOPBACK_PREFIX IPV4_ADDR(127, 0, 0, 0)
111 #define IPV4_LOOPBACK_MASK IPV4_ADDR(255, 0, 0, 0)
112 
113 //Link-local addresses
114 #define IPV4_LINK_LOCAL_PREFIX IPV4_ADDR(169, 254, 0, 0)
115 #define IPV4_LINK_LOCAL_MASK IPV4_ADDR(255, 255, 0, 0)
116 
117 //Multicast addresses
118 #define IPV4_MULTICAST_PREFIX IPV4_ADDR(224, 0, 0, 0)
119 #define IPV4_MULTICAST_MASK IPV4_ADDR(240, 0, 0, 0)
120 
121 //Local Network Control Block (RFC 5771)
122 #define IPV4_MULTICAST_LNCB_PREFIX IPV4_ADDR(224, 0, 0, 0)
123 #define IPV4_MULTICAST_LNCB_MASK IPV4_ADDR(255, 255, 255, 0)
124 
125 //Internetwork Control Block (RFC 5771)
126 #define IPV4_MULTICAST_INCB_PREFIX IPV4_ADDR(224, 0, 1, 0)
127 #define IPV4_MULTICAST_INCB_MASK IPV4_ADDR(255, 255, 255, 0)
128 
129 //IPv4 address classes
130 #define IPV4_CLASS_A_ADDR IPV4_ADDR(0, 0, 0, 0)
131 #define IPV4_CLASS_A_MASK IPV4_ADDR(128, 0, 0, 0)
132 #define IPV4_CLASS_B_ADDR IPV4_ADDR(128, 0, 0, 0)
133 #define IPV4_CLASS_B_MASK IPV4_ADDR(192, 0, 0, 0)
134 #define IPV4_CLASS_C_ADDR IPV4_ADDR(192, 0, 0, 0)
135 #define IPV4_CLASS_C_MASK IPV4_ADDR(224, 0, 0, 0)
136 #define IPV4_CLASS_D_ADDR IPV4_ADDR(224, 0, 0, 0)
137 #define IPV4_CLASS_D_MASK IPV4_ADDR(240, 0, 0, 0)
138 #define IPV4_CLASS_E_ADDR IPV4_ADDR(240, 0, 0, 0)
139 #define IPV4_CLASS_E_MASK IPV4_ADDR(240, 0, 0, 0)
140 
141 //Copy IPv4 address
142 #define ipv4CopyAddr(destIpAddr, srcIpAddr) \
143  memcpy(destIpAddr, srcIpAddr, sizeof(Ipv4Addr))
144 
145 //Compare IPv4 addresses
146 #define ipv4CompAddr(ipAddr1, ipAddr2) \
147  (!memcmp(ipAddr1, ipAddr2, sizeof(Ipv4Addr)))
148 
149 //Determine whether an IPv4 address belongs to the subnet
150 #define ipv4IsOnSubnet(entry, ipAddr) \
151  (((ipAddr) & (entry)->subnetMask) == ((entry)->addr & (entry)->subnetMask))
152 
153 //Determine whether an IPv4 address is a loopback address
154 #define ipv4IsLoopbackAddr(ipAddr) \
155  (((ipAddr) & IPV4_LOOPBACK_MASK) == IPV4_LOOPBACK_PREFIX)
156 
157 //Determine whether an IPv4 address is a link-local address
158 #define ipv4IsLinkLocalAddr(ipAddr) \
159  (((ipAddr) & IPV4_LINK_LOCAL_MASK) == IPV4_LINK_LOCAL_PREFIX)
160 
161 //Determine whether an IPv4 address is a multicast address
162 #define ipv4IsMulticastAddr(ipAddr) \
163  (((ipAddr) & IPV4_MULTICAST_MASK) == IPV4_MULTICAST_PREFIX)
164 
165 //C++ guard
166 #ifdef __cplusplus
167 extern "C" {
168 #endif
169 
170 
171 /**
172  * @brief IPv4 address scopes
173  **/
174 
175 typedef enum
176 {
180 } Ipv4AddrScope;
181 
182 
183 /**
184  * @brief IPv4 address state
185  **/
186 
187 typedef enum
188 {
189  IPV4_ADDR_STATE_INVALID = 0, ///<An address that is not assigned to any interface
190  IPV4_ADDR_STATE_TENTATIVE = 1, ///<An address whose uniqueness on a link is being verified
191  IPV4_ADDR_STATE_VALID = 2 ///<An address assigned to an interface whose use is unrestricted
192 } Ipv4AddrState;
193 
194 
195 /**
196  * @brief IPv4 fragment offset field
197  **/
198 
199 typedef enum
200 {
201  IPV4_FLAG_RES = 0x8000,
202  IPV4_FLAG_DF = 0x4000,
203  IPV4_FLAG_MF = 0x2000,
206 
207 
208 /**
209  * @brief IPv4 protocol field
210  **/
211 
212 typedef enum
213 {
220 } Ipv4Protocol;
221 
222 
223 /**
224  * @brief IPv4 option types
225  **/
226 
227 typedef enum
228 {
233 
234 
235 /**
236  * @brief IPv4 network address
237  **/
238 
239 typedef uint32_t Ipv4Addr;
240 
241 
242 //CodeWarrior or Win32 compiler?
243 #if defined(__CWCC__) || defined(_WIN32)
244  #pragma pack(push, 1)
245 #endif
246 
247 
248 /**
249  * @brief IPv4 header
250  **/
251 
252 __start_packed struct _Ipv4Header
253 {
254 #ifdef _CPU_BIG_ENDIAN
255  uint8_t version : 4; //0
256  uint8_t headerLength : 4;
257 #else
258  uint8_t headerLength : 4; //0
259  uint8_t version : 4;
260 #endif
261  uint8_t typeOfService; //1
262  uint16_t totalLength; //2-3
263  uint16_t identification; //4-5
264  uint16_t fragmentOffset; //6-7
265  uint8_t timeToLive; //8
266  uint8_t protocol; //9
267  uint16_t headerChecksum; //10-11
268  Ipv4Addr srcAddr; //12-15
270  uint8_t options[]; //20
271 } __end_packed;
272 
273 
274 /**
275  * @brief IPv4 pseudo header
276  **/
277 
278 __start_packed struct _Ipv4PseudoHeader
279 {
282  uint8_t reserved; //8
283  uint8_t protocol; //9
284  uint16_t length; //10-11
285 } __end_packed;
286 
287 
288 /**
289  * @brief IPv4 option
290  **/
291 
292 typedef __start_packed struct
293 {
294  uint8_t type; //0
295  uint8_t length; //1
296  uint8_t value[]; //2
298 
299 
300 //CodeWarrior or Win32 compiler?
301 #if defined(__CWCC__) || defined(_WIN32)
302  #pragma pack(pop)
303 #endif
304 
305 
306 /**
307  * @brief IPv4 address entry
308  **/
309 
310 typedef struct
311 {
312  Ipv4Addr addr; ///<IPv4 address
313  Ipv4AddrState state; ///<IPv4 address state
314  bool_t conflict; ///<Address conflict detected
315  Ipv4Addr subnetMask; ///<Subnet mask
316  Ipv4Addr defaultGateway; ///<Default gateway
317 } Ipv4AddrEntry;
318 
319 
320 /**
321  * @brief IPv4 multicast filter entry
322  **/
323 
324 typedef struct
325 {
326  Ipv4Addr addr; ///<Multicast address
327  uint_t refCount; ///<Reference count for the current entry
328  uint_t state; ///<IGMP host state
329  bool_t flag; ///<IGMP flag
330  systime_t timer; ///<Delay timer
332 
333 
334 /**
335  * @brief IPv4 context
336  **/
337 
338 typedef struct
339 {
340  size_t linkMtu; ///<Maximum transmission unit
341  bool_t isRouter; ///<A flag indicating whether routing is enabled on this interface
342  bool_t enableBroadcastEchoReq; ///<Support for broadcast ICMP Echo Request messages
343  uint16_t identification; ///<IPv4 fragment identification field
344  Ipv4AddrEntry addrList[IPV4_ADDR_LIST_SIZE]; ///<IPv4 address list
345  Ipv4Addr dnsServerList[IPV4_DNS_SERVER_LIST_SIZE]; ///<DNS servers
346  Ipv4FilterEntry multicastFilter[IPV4_MULTICAST_FILTER_SIZE]; ///<Multicast filter table
347 #if (IPV4_FRAG_SUPPORT == ENABLED)
348  Ipv4FragDesc fragQueue[IPV4_MAX_FRAG_DATAGRAMS]; ///<IPv4 fragment reassembly queue
349 #endif
350 } Ipv4Context;
351 
352 
353 //IPv4 related functions
354 error_t ipv4Init(NetInterface *interface);
355 
360 
365 
367 
369  Ipv4Addr addr);
370 
372 
374  Ipv4Addr *addr);
375 
378 
379 void ipv4LinkChangeEvent(NetInterface *interface);
380 
381 void ipv4ProcessPacket(NetInterface *interface, Ipv4Header *packet, size_t length);
382 void ipv4ProcessDatagram(NetInterface *interface, const NetBuffer *buffer);
383 
384 error_t ipv4SendDatagram(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader,
385  NetBuffer *buffer, size_t offset, uint_t flags);
386 
387 error_t ipv4SendPacket(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader,
388  uint16_t fragId, size_t fragOffset, NetBuffer *buffer, size_t offset,
389  uint_t flags);
390 
393 
396 
397 void ipv4DumpHeader(const Ipv4Header *ipHeader);
398 
399 //C++ guard
400 #ifdef __cplusplus
401 }
402 #endif
403 
404 #endif
error_t ipv4LeaveMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr)
Leave the specified host group.
Definition: ipv4.c:1303
uint16_t fragmentOffset
Definition: ipv4.h:264
int bool_t
Definition: compiler_port.h:49
#define Ipv4Header
Definition: ipv4.h:36
Ipv4Addr addr
IPv4 address.
Definition: ipv4.h:312
@ IPV4_PROTOCOL_ICMP
Definition: ipv4.h:214
@ IPV4_OFFSET_MASK
Definition: ipv4.h:204
@ IPV4_ADDR_SCOPE_LINK_LOCAL
Definition: ipv4.h:178
error_t ipv4Init(NetInterface *interface)
IPv4 related initialization.
Definition: ipv4.c:72
void ipv4DumpHeader(const Ipv4Header *ipHeader)
Dump IPv4 header for debugging purpose.
Definition: ipv4.c:1490
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
uint_t state
IGMP host state.
Definition: ipv4.h:328
void ipv4LinkChangeEvent(NetInterface *interface)
Callback function for link change event.
Definition: ipv4.c:517
error_t ipv4SetDefaultGateway(NetInterface *interface, Ipv4Addr addr)
Configure default gateway.
Definition: ipv4.c:351
Ipv4AddrState
IPv4 address state.
Definition: ipv4.h:187
uint16_t identification
Definition: ipv4.h:263
uint8_t options[]
Definition: ipv4.h:270
Ipv4Addr destAddr
Definition: ipv4.h:269
Ipv4AddrState state
IPv4 address state.
Definition: ipv4.h:313
Ipv4Addr srcAddr
Definition: ipv4.h:268
error_t ipv4GetHostAddr(NetInterface *interface, Ipv4Addr *addr)
Retrieve host address.
Definition: ipv4.c:193
@ IPV4_OPTION_NOP
Definition: ipv4.h:230
IPv4 header.
Definition: ipv4.h:252
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
error_t ipv4GetDnsServer(NetInterface *interface, uint_t index, Ipv4Addr *addr)
Retrieve DNS server.
Definition: ipv4.c:485
IPv4 context.
Definition: ipv4.h:338
Ipv4Addr srcAddr
Definition: ipv4.h:280
Ethernet.
bool_t isRouter
A flag indicating whether routing is enabled on this interface.
Definition: ipv4.h:341
uint8_t reserved
Definition: ipv4.h:282
uint8_t typeOfService
Definition: ipv4.h:261
error_t ipv4SendDatagram(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, uint_t flags)
Send an IPv4 datagram.
Definition: ipv4.c:878
error_t ipv4GetSubnetMaskEx(NetInterface *interface, uint_t index, Ipv4Addr *mask)
Retrieve subnet mask.
Definition: ipv4.c:317
error_t ipv4GetDefaultGateway(NetInterface *interface, Ipv4Addr *addr)
Retrieve default gateway.
Definition: ipv4.c:400
@ IPV4_PROTOCOL_TCP
Definition: ipv4.h:216
error_t ipv4SetHostAddrEx(NetInterface *interface, uint_t index, Ipv4Addr addr)
Assign host address.
Definition: ipv4.c:134
Ipv4FragmentOffset
IPv4 fragment offset field.
Definition: ipv4.h:199
uint8_t value[]
Definition: ipv4.h:296
@ IPV4_PROTOCOL_AH
Definition: ipv4.h:219
Ipv4Addr defaultGateway
Default gateway.
Definition: ipv4.h:316
Ipv4AddrScope
IPv4 address scopes.
Definition: ipv4.h:175
size_t linkMtu
Maximum transmission unit.
Definition: ipv4.h:340
error_t
Error codes.
Definition: error.h:42
@ IPV4_ADDR_STATE_TENTATIVE
An address whose uniqueness on a link is being verified.
Definition: ipv4.h:190
error_t ipv4SendPacket(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, uint16_t fragId, size_t fragOffset, NetBuffer *buffer, size_t offset, uint_t flags)
Send an IPv4 packet.
Definition: ipv4.c:946
@ IPV4_FLAG_MF
Definition: ipv4.h:203
uint8_t protocol
Definition: ipv4.h:283
Ipv4OptionType
IPv4 option types.
Definition: ipv4.h:227
#define IPV4_DNS_SERVER_LIST_SIZE
Definition: ipv4.h:70
#define NetInterface
Definition: net.h:36
uint8_t protocol
Definition: ipv4.h:266
uint16_t identification
IPv4 fragment identification field.
Definition: ipv4.h:343
@ IPV4_FLAG_DF
Definition: ipv4.h:202
__start_packed struct _Ipv4Header __end_packed
IPv4 multicast filter entry.
Definition: ipv4.h:324
uint8_t timeToLive
Definition: ipv4.h:265
uint16_t length
Definition: ipv4.h:284
uint8_t mask
Definition: web_socket.h:317
uint8_t fragOffset[3]
Definition: dtls_misc.h:189
error_t ipv4GetDefaultGatewayEx(NetInterface *interface, uint_t index, Ipv4Addr *addr)
Retrieve default gateway.
Definition: ipv4.c:415
#define Ipv4PseudoHeader
Definition: ipv4.h:39
#define IPV4_ADDR_LIST_SIZE
Definition: ipv4.h:63
Ipv4Addr destAddr
Definition: ipv4.h:281
uint8_t length
Definition: ipv4.h:295
IPv4 address entry.
Definition: ipv4.h:310
@ IPV4_FLAG_RES
Definition: ipv4.h:201
systime_t timer
Delay timer.
Definition: ipv4.h:330
uint8_t headerLength
Definition: ipv4.h:258
bool_t flag
IGMP flag.
Definition: ipv4.h:329
@ IPV4_PROTOCOL_IGMP
Definition: ipv4.h:215
@ IPV4_ADDR_SCOPE_INTERFACE_LOCAL
Definition: ipv4.h:177
Fragmented packet descriptor.
Definition: ipv4_frag.h:123
uint8_t flags
Definition: tcp.h:314
#define IPV4_MAX_FRAG_DATAGRAMS
Definition: ipv4_frag.h:55
char char_t
Definition: compiler_port.h:43
void ipv4ProcessDatagram(NetInterface *interface, const NetBuffer *buffer)
Incoming IPv4 datagram processing.
Definition: ipv4.c:734
Ipv4Addr addr
Multicast address.
Definition: ipv4.h:326
@ IPV4_OPTION_EEOL
Definition: ipv4.h:229
Ipv4Addr subnetMask
Subnet mask.
Definition: ipv4.h:315
IPv4 fragmentation and reassembly.
@ IPV4_PROTOCOL_UDP
Definition: ipv4.h:217
error_t ipv4GetHostAddrEx(NetInterface *interface, uint_t index, Ipv4Addr *addr)
Retrieve host address.
Definition: ipv4.c:208
uint8_t version
Definition: ipv4.h:259
@ IPV4_ADDR_STATE_INVALID
An address that is not assigned to any interface.
Definition: ipv4.h:189
@ IPV4_PROTOCOL_ESP
Definition: ipv4.h:218
uint16_t totalLength
Definition: ipv4.h:262
error_t ipv4GetSubnetMask(NetInterface *interface, Ipv4Addr *mask)
Retrieve subnet mask.
Definition: ipv4.c:302
error_t ipv4SetHostAddr(NetInterface *interface, Ipv4Addr addr)
Assign host address.
Definition: ipv4.c:119
uint16_t headerChecksum
Definition: ipv4.h:267
Ipv4Addr groupAddr
Definition: igmp.h:127
IPv4 pseudo header.
Definition: ipv4.h:278
error_t ipv4JoinMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr)
Join the specified host group.
Definition: ipv4.c:1194
__start_packed struct @170 Ipv4Option
IPv4 option.
@ IPV4_OPTION_RTRALT
Definition: ipv4.h:231
Ipv4Protocol
IPv4 protocol field.
Definition: ipv4.h:212
uint_t refCount
Reference count for the current entry.
Definition: ipv4.h:327
@ IPV4_ADDR_STATE_VALID
An address assigned to an interface whose use is unrestricted.
Definition: ipv4.h:191
void ipv4ProcessPacket(NetInterface *interface, Ipv4Header *packet, size_t length)
Incoming IPv4 packet processing.
Definition: ipv4.c:565
Ipv4Addr addr
Definition: nbns_common.h:121
bool_t conflict
Address conflict detected.
Definition: ipv4.h:314
error_t ipv4SetDnsServer(NetInterface *interface, uint_t index, Ipv4Addr addr)
Configure DNS server.
Definition: ipv4.c:451
char_t * ipv4AddrToString(Ipv4Addr ipAddr, char_t *str)
Convert a binary IPv4 address to dot-decimal notation.
Definition: ipv4.c:1466
error_t ipv4StringToAddr(const char_t *str, Ipv4Addr *ipAddr)
Convert a dot-decimal string to a binary IPv4 address.
Definition: ipv4.c:1379
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t type
Definition: ipv4.h:294
bool_t enableBroadcastEchoReq
Support for broadcast ICMP Echo Request messages.
Definition: ipv4.h:342
error_t ipv4SetDefaultGatewayEx(NetInterface *interface, uint_t index, Ipv4Addr addr)
Configure default gateway.
Definition: ipv4.c:366
error_t ipv4SetSubnetMaskEx(NetInterface *interface, uint_t index, Ipv4Addr mask)
Configure subnet mask.
Definition: ipv4.c:273
uint32_t systime_t
Definition: compiler_port.h:46
uint8_t ipAddr[4]
Definition: mib_common.h:187
error_t ipv4SetSubnetMask(NetInterface *interface, Ipv4Addr mask)
Configure subnet mask.
Definition: ipv4.c:258
@ IPV4_ADDR_SCOPE_GLOBAL
Definition: ipv4.h:179
#define IPV4_MULTICAST_FILTER_SIZE
Definition: ipv4.h:77