Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ipv4.h
00001 /** 00002 * @file ipv4.h 00003 * @brief IPv4 (Internet Protocol Version 4) 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 #ifndef _IPV4_H 00030 #define _IPV4_H 00031 00032 //Forward declaration of structures 00033 struct _Ipv4Header; 00034 #define Ipv4Header struct _Ipv4Header 00035 00036 struct _Ipv4PseudoHeader; 00037 #define Ipv4PseudoHeader struct _Ipv4PseudoHeader 00038 00039 //Dependencies 00040 #include <string.h> 00041 #include "core/net.h" 00042 #include "core/ethernet.h" 00043 #include "ipv4/ipv4_frag.h" 00044 00045 //IPv4 support 00046 #ifndef IPV4_SUPPORT 00047 #define IPV4_SUPPORT ENABLED 00048 #elif (IPV4_SUPPORT != ENABLED && IPV4_SUPPORT != DISABLED) 00049 #error IPV4_SUPPORT parameter is not valid 00050 #endif 00051 00052 //Default IPv4 time-to-live value 00053 #ifndef IPV4_DEFAULT_TTL 00054 #define IPV4_DEFAULT_TTL 64 00055 #elif (IPV4_DEFAULT_TTL < 1) 00056 #error IPV4_DEFAULT_TTL parameter is not valid 00057 #endif 00058 00059 //Maximum number of DNS servers 00060 #ifndef IPV4_DNS_SERVER_LIST_SIZE 00061 #define IPV4_DNS_SERVER_LIST_SIZE 2 00062 #elif (IPV4_DNS_SERVER_LIST_SIZE < 1) 00063 #error IPV4_DNS_SERVER_LIST_SIZE parameter is not valid 00064 #endif 00065 00066 //Size of the IPv4 multicast filter 00067 #ifndef IPV4_MULTICAST_FILTER_SIZE 00068 #define IPV4_MULTICAST_FILTER_SIZE 4 00069 #elif (IPV4_MULTICAST_FILTER_SIZE < 1) 00070 #error IPV4_MULTICAST_FILTER_SIZE parameter is not valid 00071 #endif 00072 00073 //Version number for IPv4 00074 #define IPV4_VERSION 4 00075 //Minimum MTU 00076 #define IPV4_MINIMUM_MTU 68 00077 //Default MTU 00078 #define IPV4_DEFAULT_MTU 576 00079 //Minimum header length 00080 #define IPV4_MIN_HEADER_LENGTH 20 00081 //Maximum header length 00082 #define IPV4_MAX_HEADER_LENGTH 60 00083 00084 //Shortcut to data field 00085 #define IPV4_DATA(packet) PTR_OFFSET(packet, packet->headerLength * 4) 00086 00087 //Macro used for defining an IPv4 address 00088 #ifdef _CPU_BIG_ENDIAN 00089 #define IPV4_ADDR(a, b, c, d) (((uint32_t) (a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 00090 #else 00091 #define IPV4_ADDR(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((uint32_t) (d) << 24)) 00092 #endif 00093 00094 //Unspecified IPv4 address 00095 #define IPV4_UNSPECIFIED_ADDR IPV4_ADDR(0, 0, 0, 0) 00096 //Broadcast IPV4 address 00097 #define IPV4_BROADCAST_ADDR IPV4_ADDR(255, 255, 255, 255) 00098 00099 //Loopback IPv4 address 00100 #define IPV4_LOOPBACK_ADDR IPV4_ADDR(127, 0, 0, 1) 00101 #define IPV4_LOOPBACK_ADDR_PREFIX IPV4_ADDR(127, 0, 0, 0) 00102 #define IPV4_LOOPBACK_ADDR_MASK IPV4_ADDR(255, 0, 0, 0) 00103 00104 //Link-local addresses 00105 #define IPV4_LINK_LOCAL_PREFIX IPV4_ADDR(169, 254, 0, 0) 00106 #define IPV4_LINK_LOCAL_MASK IPV4_ADDR(255, 255, 0, 0) 00107 00108 //Multicast addresses 00109 #define IPV4_MULTICAST_PREFIX IPV4_ADDR(224, 0, 0, 0) 00110 #define IPV4_MULTICAST_MASK IPV4_ADDR(240, 0, 0, 0) 00111 00112 //Local Network Control Block (RFC 5771) 00113 #define IPV4_MULTICAST_LNCB_PREFIX IPV4_ADDR(224, 0, 0, 0) 00114 #define IPV4_MULTICAST_LNCB_MASK IPV4_ADDR(255, 255, 255, 0) 00115 00116 //Internetwork Control Block (RFC 5771) 00117 #define IPV4_MULTICAST_INCB_PREFIX IPV4_ADDR(224, 0, 1, 0) 00118 #define IPV4_MULTICAST_INCB_MASK IPV4_ADDR(255, 255, 255, 0) 00119 00120 //IPv4 address classes 00121 #define IPV4_CLASS_A_ADDR IPV4_ADDR(0, 0, 0, 0) 00122 #define IPV4_CLASS_A_MASK IPV4_ADDR(128, 0, 0, 0) 00123 #define IPV4_CLASS_B_ADDR IPV4_ADDR(128, 0, 0, 0) 00124 #define IPV4_CLASS_B_MASK IPV4_ADDR(192, 0, 0, 0) 00125 #define IPV4_CLASS_C_ADDR IPV4_ADDR(192, 0, 0, 0) 00126 #define IPV4_CLASS_C_MASK IPV4_ADDR(224, 0, 0, 0) 00127 #define IPV4_CLASS_D_ADDR IPV4_ADDR(224, 0, 0, 0) 00128 #define IPV4_CLASS_D_MASK IPV4_ADDR(240, 0, 0, 0) 00129 #define IPV4_CLASS_E_ADDR IPV4_ADDR(240, 0, 0, 0) 00130 #define IPV4_CLASS_E_MASK IPV4_ADDR(240, 0, 0, 0) 00131 00132 //Copy IPv4 address 00133 #define ipv4CopyAddr(destIpAddr, srcIpAddr) \ 00134 memcpy(destIpAddr, srcIpAddr, sizeof(Ipv4Addr)) 00135 00136 //Compare IPv4 addresses 00137 #define ipv4CompAddr(ipAddr1, ipAddr2) \ 00138 (!memcmp(ipAddr1, ipAddr2, sizeof(Ipv4Addr))) 00139 00140 //Determine whether an IPv4 address belongs to the local network 00141 #define ipv4IsOnLocalSubnet(interface, ipAddr) \ 00142 ((ipAddr & interface->ipv4Context.subnetMask) == \ 00143 (interface->ipv4Context.addr & interface->ipv4Context.subnetMask)) 00144 00145 //Determine whether an IPv4 address is a link-local address 00146 #define ipv4IsLinkLocalAddr(ipAddr) \ 00147 ((ipAddr & IPV4_LINK_LOCAL_MASK) == IPV4_LINK_LOCAL_PREFIX) 00148 00149 //Determine whether an IPv4 address is a multicast address 00150 #define ipv4IsMulticastAddr(ipAddr) \ 00151 ((ipAddr & IPV4_MULTICAST_MASK) == IPV4_MULTICAST_PREFIX) 00152 00153 //Check whether an IPv4 address is a tentative address 00154 #define ipv4IsTentativeAddr(interface, ipAddr) \ 00155 (interface->ipv4Context.addrState == IPV4_ADDR_STATE_TENTATIVE && \ 00156 interface->ipv4Context.addr == ipAddr) 00157 00158 00159 /** 00160 * @brief IPv4 address scopes 00161 **/ 00162 00163 typedef enum 00164 { 00165 IPV4_ADDR_SCOPE_INTERFACE_LOCAL = 1, 00166 IPV4_ADDR_SCOPE_LINK_LOCAL = 2, 00167 IPV4_ADDR_SCOPE_GLOBAL = 3 00168 } Ipv4AddrScope; 00169 00170 00171 /** 00172 * @brief IPv4 address state 00173 **/ 00174 00175 typedef enum 00176 { 00177 IPV4_ADDR_STATE_INVALID = 0, ///<An address that is not assigned to any interface 00178 IPV4_ADDR_STATE_TENTATIVE = 1, ///<An address whose uniqueness on a link is being verified 00179 IPV4_ADDR_STATE_VALID = 2 ///<An address assigned to an interface whose use is unrestricted 00180 } Ipv4AddrState; 00181 00182 00183 /** 00184 * @brief IPv4 fragment offset field 00185 **/ 00186 00187 typedef enum 00188 { 00189 IPV4_FLAG_RES = 0x8000, 00190 IPV4_FLAG_DF = 0x4000, 00191 IPV4_FLAG_MF = 0x2000, 00192 IPV4_OFFSET_MASK = 0x1FFF 00193 } Ipv4FragmentOffset; 00194 00195 00196 /** 00197 * @brief IPv4 protocol field 00198 **/ 00199 00200 typedef enum 00201 { 00202 IPV4_PROTOCOL_ICMP = 1, 00203 IPV4_PROTOCOL_IGMP = 2, 00204 IPV4_PROTOCOL_TCP = 6, 00205 IPV4_PROTOCOL_UDP = 17 00206 } Ipv4Protocol; 00207 00208 00209 /** 00210 * @brief IPv4 option types 00211 **/ 00212 00213 typedef enum 00214 { 00215 IPV4_OPTION_EEOL = 0, 00216 IPV4_OPTION_NOP = 1, 00217 IPV4_OPTION_RTRALT = 148 00218 } Ipv4OptionType; 00219 00220 00221 /** 00222 * @brief IPv4 network address 00223 **/ 00224 00225 typedef uint32_t Ipv4Addr; 00226 00227 00228 //CodeWarrior or Win32 compiler? 00229 #if defined(__CWCC__) || defined(_WIN32) 00230 #pragma pack(push, 1) 00231 #endif 00232 00233 00234 /** 00235 * @brief IPv4 header 00236 **/ 00237 00238 __start_packed struct _Ipv4Header 00239 { 00240 #ifdef _CPU_BIG_ENDIAN 00241 uint8_t version : 4; //0 00242 uint8_t headerLength : 4; 00243 #else 00244 uint8_t headerLength : 4; //0 00245 uint8_t version : 4; 00246 #endif 00247 uint8_t typeOfService; //1 00248 uint16_t totalLength; //2-3 00249 uint16_t identification; //4-5 00250 uint16_t fragmentOffset; //6-7 00251 uint8_t timeToLive; //8 00252 uint8_t protocol; //9 00253 uint16_t headerChecksum; //10-11 00254 Ipv4Addr srcAddr; //12-15 00255 Ipv4Addr destAddr; //16-19 00256 uint8_t options[]; //20 00257 } __end_packed; 00258 00259 00260 /** 00261 * @brief IPv4 pseudo header 00262 **/ 00263 00264 __start_packed struct _Ipv4PseudoHeader 00265 { 00266 Ipv4Addr srcAddr; //0-3 00267 Ipv4Addr destAddr; //4-7 00268 uint8_t reserved; //8 00269 uint8_t protocol; //9 00270 uint16_t length; //10-11 00271 } __end_packed; 00272 00273 00274 /** 00275 * @brief IPv4 option 00276 **/ 00277 00278 typedef __start_packed struct 00279 { 00280 uint8_t type; //0 00281 uint8_t length; //1 00282 uint8_t value[]; //2 00283 } __end_packed Ipv4Option; 00284 00285 00286 //CodeWarrior or Win32 compiler? 00287 #if defined(__CWCC__) || defined(_WIN32) 00288 #pragma pack(pop) 00289 #endif 00290 00291 00292 /** 00293 * @brief IPv4 multicast filter entry 00294 **/ 00295 00296 typedef struct 00297 { 00298 Ipv4Addr addr; ///<Multicast address 00299 uint_t refCount; ///<Reference count for the current entry 00300 uint_t state; ///<IGMP host state 00301 bool_t flag; ///<IGMP flag 00302 systime_t timer; ///<Delay timer 00303 } Ipv4FilterEntry; 00304 00305 00306 /** 00307 * @brief IPv4 context 00308 **/ 00309 00310 typedef struct 00311 { 00312 size_t linkMtu; ///<Maximum transmission unit 00313 bool_t isRouter; ///<A flag indicating whether routing is enabled on this interface 00314 uint16_t identification; ///<IPv4 fragment identification field 00315 Ipv4Addr addr; ///<Host address 00316 Ipv4AddrState addrState; ///<State of the host address 00317 bool_t addrConflict; ///<Address conflict detected 00318 Ipv4Addr subnetMask; ///<Subnet mask 00319 Ipv4Addr defaultGateway; ///<Default gateway 00320 Ipv4Addr dnsServerList[IPV4_DNS_SERVER_LIST_SIZE]; ///<DNS servers 00321 Ipv4FilterEntry multicastFilter[IPV4_MULTICAST_FILTER_SIZE]; ///<Multicast filter table 00322 #if (IPV4_FRAG_SUPPORT == ENABLED) 00323 Ipv4FragDesc fragQueue[IPV4_MAX_FRAG_DATAGRAMS]; ///<IPv4 fragment reassembly queue 00324 #endif 00325 } Ipv4Context; 00326 00327 00328 //IPv4 related functions 00329 error_t ipv4Init(NetInterface *interface); 00330 00331 error_t ipv4SetHostAddr(NetInterface *interface, Ipv4Addr addr); 00332 error_t ipv4GetHostAddr(NetInterface *interface, Ipv4Addr *addr); 00333 00334 error_t ipv4SetSubnetMask(NetInterface *interface, Ipv4Addr mask); 00335 error_t ipv4GetSubnetMask(NetInterface *interface, Ipv4Addr *mask); 00336 00337 error_t ipv4SetDefaultGateway(NetInterface *interface, Ipv4Addr addr); 00338 error_t ipv4GetDefaultGateway(NetInterface *interface, Ipv4Addr *addr); 00339 00340 error_t ipv4SetDnsServer(NetInterface *interface, uint_t index, Ipv4Addr addr); 00341 error_t ipv4GetDnsServer(NetInterface *interface, uint_t index, Ipv4Addr *addr); 00342 00343 error_t ipv4GetBroadcastAddr(NetInterface *interface, Ipv4Addr *addr); 00344 00345 void ipv4LinkChangeEvent(NetInterface *interface); 00346 00347 void ipv4ProcessPacket(NetInterface *interface, Ipv4Header *packet, size_t length); 00348 void ipv4ProcessDatagram(NetInterface *interface, const NetBuffer *buffer); 00349 00350 error_t ipv4SendDatagram(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, 00351 NetBuffer *buffer, size_t offset, uint8_t ttl); 00352 00353 error_t ipv4SendPacket(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, 00354 uint16_t fragId, size_t fragOffset, NetBuffer *buffer, size_t offset, uint8_t ttl); 00355 00356 error_t ipv4CheckSourceAddr(NetInterface *interface, Ipv4Addr ipAddr); 00357 error_t ipv4CheckDestAddr(NetInterface *interface, Ipv4Addr ipAddr); 00358 00359 error_t ipv4SelectSourceAddr(NetInterface **interface, 00360 Ipv4Addr destAddr, Ipv4Addr *srcAddr); 00361 00362 bool_t ipv4IsBroadcastAddr(NetInterface *interface, Ipv4Addr ipAddr); 00363 00364 uint_t ipv4GetAddrScope(Ipv4Addr ipAddr); 00365 00366 error_t ipv4JoinMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr); 00367 error_t ipv4LeaveMulticastGroup(NetInterface *interface, Ipv4Addr groupAddr); 00368 00369 error_t ipv4MapMulticastAddrToMac(Ipv4Addr ipAddr, MacAddr *macAddr); 00370 00371 error_t ipv4StringToAddr(const char_t *str, Ipv4Addr *ipAddr); 00372 char_t *ipv4AddrToString(Ipv4Addr ipAddr, char_t *str); 00373 00374 void ipv4DumpHeader(const Ipv4Header *ipHeader); 00375 00376 #endif 00377
Generated on Tue Jul 12 2022 17:10:13 by
