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