Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ipv4.h Source File

ipv4.h

Go to the documentation of this file.
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