Sergey Pastor / 1

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ipv6.h Source File

ipv6.h

Go to the documentation of this file.
00001 /**
00002  * @file ipv6.h
00003  * @brief IPv6 (Internet Protocol Version 6)
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 _IPV6_H
00030 #define _IPV6_H
00031 
00032 //Forward declaration of structures
00033 struct _Ipv6Header;
00034 #define Ipv6Header struct _Ipv6Header
00035 
00036 struct _Ipv6FragmentHeader;
00037 #define Ipv6FragmentHeader struct _Ipv6FragmentHeader
00038 
00039 struct _Ipv6PseudoHeader;
00040 #define Ipv6PseudoHeader struct _Ipv6PseudoHeader
00041 
00042 //Dependencies
00043 #include <string.h>
00044 #include "core/net.h"
00045 #include "core/ethernet.h"
00046 #include "ipv6/ipv6_frag.h"
00047 
00048 //IPv6 support
00049 #ifndef IPV6_SUPPORT
00050    #define IPV6_SUPPORT DISABLED
00051 #elif (IPV6_SUPPORT != ENABLED && IPV6_SUPPORT != DISABLED)
00052    #error IPV6_SUPPORT parameter is not valid
00053 #endif
00054 
00055 //Default IPv6 Hop Limit field
00056 #ifndef IPV6_DEFAULT_HOP_LIMIT
00057    #define IPV6_DEFAULT_HOP_LIMIT 64
00058 #elif (IPV6_DEFAULT_HOP_LIMIT < 1)
00059    #error IPV6_DEFAULT_HOP_LIMIT parameter is not valid
00060 #endif
00061 
00062 //Maximum number of IPv6 unicast addresses
00063 #ifndef IPV6_ADDR_LIST_SIZE
00064    #define IPV6_ADDR_LIST_SIZE 3
00065 #elif (IPV6_ADDR_LIST_SIZE < 2)
00066    #error IPV6_ADDR_LIST_SIZE parameter is not valid
00067 #endif
00068 
00069 //Maximum number of IPv6 anycast addresses
00070 #ifndef IPV6_ANYCAST_ADDR_LIST_SIZE
00071    #define IPV6_ANYCAST_ADDR_LIST_SIZE 1
00072 #elif (IPV6_ANYCAST_ADDR_LIST_SIZE < 1)
00073    #error IPV6_ANYCAST_ADDR_LIST_SIZE parameter is not valid
00074 #endif
00075 
00076 //Size of the prefix list
00077 #ifndef IPV6_PREFIX_LIST_SIZE
00078    #define IPV6_PREFIX_LIST_SIZE 2
00079 #elif (IPV6_PREFIX_LIST_SIZE < 1)
00080    #error IPV6_PREFIX_LIST_SIZE parameter is not valid
00081 #endif
00082 
00083 //Maximum number number of default routers
00084 #ifndef IPV6_ROUTER_LIST_SIZE
00085    #define IPV6_ROUTER_LIST_SIZE 2
00086 #elif (IPV6_ROUTER_LIST_SIZE < 1)
00087    #error IPV6_ROUTER_LIST_SIZE parameter is not valid
00088 #endif
00089 
00090 //Maximum number of DNS servers
00091 #ifndef IPV6_DNS_SERVER_LIST_SIZE
00092    #define IPV6_DNS_SERVER_LIST_SIZE 2
00093 #elif (IPV6_DNS_SERVER_LIST_SIZE < 1)
00094    #error IPV6_DNS_SERVER_LIST_SIZE parameter is not valid
00095 #endif
00096 
00097 //Size of the IPv6 multicast filter
00098 #ifndef IPV6_MULTICAST_FILTER_SIZE
00099    #define IPV6_MULTICAST_FILTER_SIZE 8
00100 #elif (IPV6_MULTICAST_FILTER_SIZE < 1)
00101    #error IPV6_MULTICAST_FILTER_SIZE parameter is not valid
00102 #endif
00103 
00104 //Version number for IPv6
00105 #define IPV6_VERSION 6
00106 //Minimum MTU that routers and physical links are required to handle
00107 #define IPV6_DEFAULT_MTU 1280
00108 
00109 //Macro used for defining an IPv6 address
00110 #define IPV6_ADDR(a, b, c, d, e, f, g, h) {{{ \
00111    MSB(a), LSB(a), MSB(b), LSB(b), MSB(c), LSB(c), MSB(d), LSB(d), \
00112    MSB(e), LSB(e), MSB(f), LSB(f), MSB(g), LSB(g), MSB(h), LSB(h)}}}
00113 
00114 //Copy IPv6 address
00115 #define ipv6CopyAddr(destIpAddr, srcIpAddr) \
00116    memcpy(destIpAddr, srcIpAddr, sizeof(Ipv6Addr))
00117 
00118 //Compare IPv6 addresses
00119 #define ipv6CompAddr(ipAddr1, ipAddr2) \
00120    (!memcmp(ipAddr1, ipAddr2, sizeof(Ipv6Addr)))
00121 
00122 //Determine whether an IPv6 address is a link-local unicast address
00123 #define ipv6IsLinkLocalUnicastAddr(ipAddr) \
00124    ((ipAddr)->b[0] == 0xFE && ((ipAddr)->b[1] & 0xC0) == 0x80)
00125 
00126 //Determine whether an IPv6 address is a site-local unicast address
00127 #define ipv6IsSiteLocalUnicastAddr(ipAddr) \
00128    ((ipAddr)->b[0] == 0xFE && ((ipAddr)->b[1] & 0xC0) == 0xC0)
00129 
00130 //Determine whether an IPv6 address is a multicast address
00131 #define ipv6IsMulticastAddr(ipAddr) \
00132    ((ipAddr)->b[0] == 0xFF)
00133 
00134 //Determine whether an IPv6 address is a solicited-node address
00135 #define ipv6IsSolicitedNodeAddr(ipAddr) \
00136    ipv6CompPrefix(ipAddr, &IPV6_SOLICITED_NODE_ADDR_PREFIX, 104)
00137 
00138 //Get the state of the link-local address
00139 #define ipv6GetLinkLocalAddrState(interface) \
00140    (interface->ipv6Context.addrList[0].state)
00141 
00142 
00143 /**
00144  * @brief IPv6 address scopes
00145  **/
00146 
00147 typedef enum
00148 {
00149    IPV6_ADDR_SCOPE_INTERFACE_LOCAL    = 1,
00150    IPV6_ADDR_SCOPE_LINK_LOCAL         = 2,
00151    IPV6_ADDR_SCOPE_ADMIN_LOCAL        = 4,
00152    IPV6_ADDR_SCOPE_SITE_LOCAL         = 5,
00153    IPV6_ADDR_SCOPE_ORGANIZATION_LOCAL = 8,
00154    IPV6_ADDR_SCOPE_GLOBAL             = 14
00155 } Ipv6AddrScope;
00156 
00157 
00158 /**
00159  * @brief IPv6 address state
00160  **/
00161 
00162 typedef enum
00163 {
00164    IPV6_ADDR_STATE_INVALID    = 0, ///<An address that is not assigned to any interface
00165    IPV6_ADDR_STATE_TENTATIVE  = 1, ///<An address whose uniqueness on a link is being verified
00166    IPV6_ADDR_STATE_PREFERRED  = 2, ///<An address assigned to an interface whose use is unrestricted
00167    IPV6_ADDR_STATE_DEPRECATED = 3  ///<An address assigned to an interface whose use is discouraged
00168 } Ipv6AddrState;
00169 
00170 
00171 /**
00172  * @brief IPv6 Next Header types
00173  **/
00174 
00175 typedef enum
00176 {
00177    IPV6_HOP_BY_HOP_OPT_HEADER = 0,
00178    IPV6_TCP_HEADER            = 6,
00179    IPV6_UDP_HEADER            = 17,
00180    IPV6_ROUTING_HEADER        = 43,
00181    IPV6_FRAGMENT_HEADER       = 44,
00182    IPV6_ESP_HEADER            = 50,
00183    IPV6_AUTH_HEADER           = 51,
00184    IPV6_ICMPV6_HEADER         = 58,
00185    IPV6_NO_NEXT_HEADER        = 59,
00186    IPV6_DEST_OPT_HEADER       = 60
00187 } Ipv6NextHeaderType;
00188 
00189 
00190 /**
00191  * @brief IPv6 fragment offset field
00192  **/
00193 
00194 typedef enum
00195 {
00196    IPV6_OFFSET_MASK = 0xFFF8,
00197    IPV6_FLAG_RES1   = 0x0004,
00198    IPV6_FLAG_RES2   = 0x0002,
00199    IPV6_FLAG_M      = 0x0001
00200 } Ipv6FragmentOffset;
00201 
00202 
00203 /**
00204  * @brief IPv6 option types
00205  **/
00206 
00207 typedef enum
00208 {
00209    IPV6_OPTION_TYPE_MASK = 0x1F,
00210    IPV6_OPTION_TYPE_PAD1 = 0x00,
00211    IPV6_OPTION_TYPE_PADN = 0x01
00212 } Ipv6OptionType;
00213 
00214 
00215 /**
00216  * @brief Actions to be taken for unrecognized options
00217  **/
00218 
00219 typedef enum
00220 {
00221    IPV6_ACTION_MASK                = 0xC0,
00222    IPV6_ACTION_SKIP_OPTION         = 0x00,
00223    IPV6_ACTION_DISCARD_PACKET      = 0x40,
00224    IPV6_ACTION_SEND_ICMP_ERROR_ALL = 0x80,
00225    IPV6_ACTION_SEND_ICMP_ERROR_UNI = 0xC0
00226 } Ipv6Actions;
00227 
00228 
00229 //CodeWarrior or Win32 compiler?
00230 #if defined(__CWCC__) || defined(_WIN32)
00231    #pragma pack(push, 1)
00232 #endif
00233 
00234 
00235 /**
00236  * @brief IPv6 network address
00237  **/
00238 
00239 typedef __start_packed struct
00240 {
00241    __start_packed union
00242    {
00243       uint8_t b[16];
00244       uint16_t w[8];
00245       uint32_t dw[4];
00246    };
00247 } __end_packed Ipv6Addr;
00248 
00249 
00250 /**
00251  * @brief IPv6 header
00252  **/
00253 
00254 __start_packed struct _Ipv6Header
00255 {
00256 #ifdef _CPU_BIG_ENDIAN
00257    uint8_t version : 4;       //0
00258    uint8_t trafficClassH : 4;
00259    uint8_t trafficClassL : 4; //1
00260    uint8_t flowLabelH : 4;
00261 #else
00262    uint8_t trafficClassH : 4; //0
00263    uint8_t version : 4;
00264    uint8_t flowLabelH : 4;    //1
00265    uint8_t trafficClassL : 4;
00266 #endif
00267    uint16_t flowLabelL;       //2-3
00268    uint16_t payloadLength;    //4-5
00269    uint8_t nextHeader;        //6
00270    uint8_t hopLimit;          //7
00271    Ipv6Addr srcAddr;          //8-23
00272    Ipv6Addr destAddr;         //24-39
00273    uint8_t payload[];         //40
00274 } __end_packed;
00275 
00276 
00277 /**
00278  * @brief IPv6 Hop-by-Hop Options header
00279  **/
00280 
00281 typedef __start_packed struct
00282 {
00283    uint8_t nextHeader; //0
00284    uint8_t hdrExtLen;  //1
00285    uint8_t options[];  //2
00286 } __end_packed Ipv6HopByHopOptHeader;
00287 
00288 
00289 /**
00290  * @brief IPv6 Destination Options header
00291  **/
00292 
00293 typedef __start_packed struct
00294 {
00295    uint8_t nextHeader; //0
00296    uint8_t hdrExtLen;  //1
00297    uint8_t options[];  //2
00298 } __end_packed Ipv6DestOptHeader;
00299 
00300 
00301 /**
00302  * @brief IPv6 Type 0 Routing header
00303  **/
00304 
00305 typedef __start_packed struct
00306 {
00307    uint8_t nextHeader;   //0
00308    uint8_t hdrExtLen;    //1
00309    uint8_t routingType;  //2
00310    uint8_t segmentsLeft; //3
00311    uint32_t reserved;    //4-7
00312    Ipv6Addr address[];   //8
00313 } __end_packed Ipv6RoutingHeader;
00314 
00315 
00316 /**
00317  * @brief IPv6 Fragment header
00318  **/
00319 
00320 __start_packed struct _Ipv6FragmentHeader
00321 {
00322    uint8_t nextHeader;      //0
00323    uint8_t reserved;        //1
00324    uint16_t fragmentOffset; //2-3
00325    uint32_t identification; //4-7
00326 } __end_packed;
00327 
00328 
00329 /**
00330  * @brief IPv6 Authentication header
00331  **/
00332 
00333 typedef __start_packed struct
00334 {
00335    uint8_t nextHeader;          //0
00336    uint8_t payloadLength;       //1
00337    uint16_t reserved;           //2-3
00338    uint32_t securityParamIndex; //4-7
00339    uint32_t sequenceNumber;     //8-11
00340    uint8_t authData[];          //12
00341 } __end_packed Ipv6AuthHeader;
00342 
00343 
00344 /**
00345  * @brief IPv6 Encapsulating Security Payload header
00346  **/
00347 
00348 typedef __start_packed struct
00349 {
00350    uint32_t securityParamIndex; //0-3
00351    uint32_t sequenceNumber;     //4-7
00352    uint8_t payloadData[];       //8
00353 } __end_packed Ipv6EspHeader;
00354 
00355 
00356 /**
00357  * @brief IPv6 option
00358  **/
00359 
00360 typedef __start_packed struct
00361 {
00362    uint8_t type;   //0
00363    uint8_t length; //1
00364    uint8_t data[]; //2
00365 } __end_packed Ipv6Option;
00366 
00367 
00368 /**
00369  * @brief IPv6 pseudo header
00370  **/
00371 
00372 __start_packed struct _Ipv6PseudoHeader
00373 {
00374    Ipv6Addr srcAddr;        //0-15
00375    Ipv6Addr destAddr;       //16-31
00376    uint32_t length;         //32-35
00377    uint32_t reserved : 24;  //36-38
00378    uint32_t nextHeader : 8; //39
00379 } __end_packed;
00380 
00381 
00382 //CodeWarrior or Win32 compiler?
00383 #if defined(__CWCC__) || defined(_WIN32)
00384    #pragma pack(pop)
00385 #endif
00386 
00387 
00388 /**
00389  * @brief IPv6 address entry
00390  **/
00391 
00392 typedef struct
00393 {
00394    Ipv6Addr addr;               ///<IPv6 address
00395    Ipv6AddrState state;         ///<IPv6 address state
00396    bool_t duplicate;            ///<The address is a duplicate
00397    systime_t validLifetime;     ///<Valid lifetime
00398    systime_t preferredLifetime; ///<Preferred lifetime
00399    bool_t permanent;            ///<Permanently assigned address
00400    systime_t timestamp;         ///<Timestamp to manage entry lifetime
00401    systime_t dadTimeout;        ///<Timeout value for Duplicate Address Detection
00402    uint_t dadRetransmitCount;   ///<Retransmission counter for Duplicate Address Detection
00403 } Ipv6AddrEntry;
00404 
00405 
00406 /**
00407  * @brief Prefix list entry
00408  **/
00409 
00410 typedef struct
00411 {
00412    Ipv6Addr prefix;             ///<IPv6 prefix information
00413    uint8_t prefixLength;        ///<IPv6 prefix length
00414    systime_t validLifetime;     ///<Valid lifetime
00415    systime_t preferredLifetime; ///<Preferred lifetime
00416    bool_t permanent;            ///<Permanently assigned prefix
00417    systime_t timestamp;         ///<Timestamp to manage entry lifetime
00418 } Ipv6PrefixEntry;
00419 
00420 
00421 /**
00422  * @brief Default router list entry
00423  **/
00424 
00425 typedef struct
00426 {
00427    Ipv6Addr addr;       ///<Router address
00428    systime_t lifetime;  ///<Router lifetime
00429    bool_t permanent;    ///<Permanently assigned router
00430    systime_t timestamp; ///<Timestamp to manage entry lifetime
00431 } Ipv6RouterEntry;
00432 
00433 
00434 /**
00435  * @brief IPv6 multicast filter entry
00436  **/
00437 
00438 typedef struct
00439 {
00440    Ipv6Addr addr;   ///<Multicast address
00441    uint_t refCount; ///<Reference count for the current entry
00442    uint_t state;    ///<MLD node state
00443    bool_t flag;     ///<MLD flag
00444    systime_t timer; ///<Delay timer
00445 } Ipv6FilterEntry;
00446 
00447 
00448 /**
00449  * @brief IPv6 context
00450  **/
00451 
00452 typedef struct
00453 {
00454    size_t linkMtu;                                              ///<Maximum transmission unit
00455    bool_t isRouter;                                             ///<A flag indicating whether routing is enabled on this interface
00456    uint8_t curHopLimit;                                         ///<Default value for the Hop Limit field
00457    bool_t enableMulticastEchoReq;                               ///<Support for multicast ICMPv6 Echo Request messages
00458    Ipv6AddrEntry addrList[IPV6_ADDR_LIST_SIZE];                 ///<IPv6 unicast address list
00459    Ipv6Addr anycastAddrList[IPV6_ANYCAST_ADDR_LIST_SIZE];       ///<IPv6 anycast address list
00460    Ipv6PrefixEntry prefixList[IPV6_PREFIX_LIST_SIZE];           ///<Prefix list
00461    Ipv6RouterEntry routerList[IPV6_ROUTER_LIST_SIZE];           ///<Default router list
00462    Ipv6Addr dnsServerList[IPV6_DNS_SERVER_LIST_SIZE];           ///<DNS servers
00463    Ipv6FilterEntry multicastFilter[IPV6_MULTICAST_FILTER_SIZE]; ///<Multicast filter table
00464 #if (IPV6_FRAG_SUPPORT == ENABLED)
00465    uint32_t identification;                                     ///<IPv6 fragment identification field
00466    Ipv6FragDesc fragQueue[IPV6_MAX_FRAG_DATAGRAMS];             ///<IPv6 fragment reassembly queue
00467 #endif
00468 } Ipv6Context;
00469 
00470 
00471 //IPv6 related constants
00472 extern const Ipv6Addr IPV6_UNSPECIFIED_ADDR;
00473 extern const Ipv6Addr IPV6_LOOPBACK_ADDR;
00474 extern const Ipv6Addr IPV6_LINK_LOCAL_ALL_NODES_ADDR;
00475 extern const Ipv6Addr IPV6_LINK_LOCAL_ALL_ROUTERS_ADDR;
00476 extern const Ipv6Addr IPV6_LINK_LOCAL_ADDR_PREFIX;
00477 extern const Ipv6Addr IPV6_SOLICITED_NODE_ADDR_PREFIX;
00478 
00479 //IPv6 related functions
00480 error_t ipv6Init(NetInterface *interface);
00481 
00482 error_t ipv6SetMtu(NetInterface *interface, size_t mtu);
00483 error_t ipv6GetMtu(NetInterface *interface, size_t *mtu);
00484 
00485 error_t ipv6SetLinkLocalAddr(NetInterface *interface, const Ipv6Addr *addr);
00486 error_t ipv6GetLinkLocalAddr(NetInterface *interface, Ipv6Addr *addr);
00487 
00488 error_t ipv6SetGlobalAddr(NetInterface *interface, uint_t index, const Ipv6Addr *addr);
00489 error_t ipv6GetGlobalAddr(NetInterface *interface, uint_t index, Ipv6Addr *addr);
00490 
00491 error_t ipv6SetAnycastAddr(NetInterface *interface, uint_t index, const Ipv6Addr *addr);
00492 error_t ipv6GetAnycastAddr(NetInterface *interface, uint_t index, Ipv6Addr *addr);
00493 
00494 error_t ipv6SetPrefix(NetInterface *interface,
00495    uint_t index, const Ipv6Addr *prefix, uint_t length);
00496 
00497 error_t ipv6GetPrefix(NetInterface *interface,
00498    uint_t index, Ipv6Addr *prefix, uint_t *length);
00499 
00500 error_t ipv6SetDefaultRouter(NetInterface *interface, uint_t index, const Ipv6Addr *addr);
00501 error_t ipv6GetDefaultRouter(NetInterface *interface, uint_t index, Ipv6Addr *addr);
00502 
00503 error_t ipv6SetDnsServer(NetInterface *interface, uint_t index, const Ipv6Addr *addr);
00504 error_t ipv6GetDnsServer(NetInterface *interface, uint_t index, Ipv6Addr *addr);
00505 
00506 void ipv6LinkChangeEvent(NetInterface *interface);
00507 
00508 void ipv6ProcessPacket(NetInterface *interface,
00509    NetBuffer *ipPacket, size_t ipPacketOffset);
00510 
00511 error_t ipv6ParseHopByHopOptHeader(NetInterface *interface, const NetBuffer *ipPacket,
00512    size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset);
00513 
00514 error_t ipv6ParseDestOptHeader(NetInterface *interface, const NetBuffer *ipPacket,
00515    size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset);
00516 
00517 error_t ipv6ParseRoutingHeader(NetInterface *interface, const NetBuffer *ipPacket,
00518    size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset);
00519 
00520 error_t ipv6ParseAuthHeader(NetInterface *interface, const NetBuffer *ipPacket,
00521    size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset);
00522 
00523 error_t ipv6ParseEspHeader(NetInterface *interface, const NetBuffer *ipPacket,
00524    size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset);
00525 
00526 error_t ipv6ParseOptions(NetInterface *interface, const NetBuffer *ipPacket,
00527    size_t ipPacketOffset, size_t optOffset, size_t optLength);
00528 
00529 error_t ipv6SendDatagram(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader,
00530    NetBuffer *buffer, size_t offset, uint8_t hopLimit);
00531 
00532 error_t ipv6SendPacket(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader,
00533    uint32_t fragId, size_t fragOffset, NetBuffer *buffer, size_t offset, uint8_t hopLimit);
00534 
00535 error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr);
00536 error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr);
00537 
00538 error_t ipv6StringToAddr(const char_t *str, Ipv6Addr *ipAddr);
00539 char_t *ipv6AddrToString(const Ipv6Addr *ipAddr, char_t *str);
00540 
00541 void ipv6DumpHeader(const Ipv6Header *ipHeader);
00542 
00543 #endif
00544