Webserver+3d print
cyclone_tcp/ipv6/ipv6.h
- Committer:
- Sergunb
- Date:
- 2017-02-04
- Revision:
- 0:8918a71cdbe9
File content as of revision 0:8918a71cdbe9:
/** * @file ipv6.h * @brief IPv6 (Internet Protocol Version 6) * * @section License * * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. * * This file is part of CycloneTCP Open. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * @author Oryx Embedded SARL (www.oryx-embedded.com) * @version 1.7.6 **/ #ifndef _IPV6_H #define _IPV6_H //Forward declaration of structures struct _Ipv6Header; #define Ipv6Header struct _Ipv6Header struct _Ipv6FragmentHeader; #define Ipv6FragmentHeader struct _Ipv6FragmentHeader struct _Ipv6PseudoHeader; #define Ipv6PseudoHeader struct _Ipv6PseudoHeader //Dependencies #include <string.h> #include "core/net.h" #include "core/ethernet.h" #include "ipv6/ipv6_frag.h" //IPv6 support #ifndef IPV6_SUPPORT #define IPV6_SUPPORT DISABLED #elif (IPV6_SUPPORT != ENABLED && IPV6_SUPPORT != DISABLED) #error IPV6_SUPPORT parameter is not valid #endif //Default IPv6 Hop Limit field #ifndef IPV6_DEFAULT_HOP_LIMIT #define IPV6_DEFAULT_HOP_LIMIT 64 #elif (IPV6_DEFAULT_HOP_LIMIT < 1) #error IPV6_DEFAULT_HOP_LIMIT parameter is not valid #endif //Maximum number of IPv6 unicast addresses #ifndef IPV6_ADDR_LIST_SIZE #define IPV6_ADDR_LIST_SIZE 3 #elif (IPV6_ADDR_LIST_SIZE < 2) #error IPV6_ADDR_LIST_SIZE parameter is not valid #endif //Maximum number of IPv6 anycast addresses #ifndef IPV6_ANYCAST_ADDR_LIST_SIZE #define IPV6_ANYCAST_ADDR_LIST_SIZE 1 #elif (IPV6_ANYCAST_ADDR_LIST_SIZE < 1) #error IPV6_ANYCAST_ADDR_LIST_SIZE parameter is not valid #endif //Size of the prefix list #ifndef IPV6_PREFIX_LIST_SIZE #define IPV6_PREFIX_LIST_SIZE 2 #elif (IPV6_PREFIX_LIST_SIZE < 1) #error IPV6_PREFIX_LIST_SIZE parameter is not valid #endif //Maximum number number of default routers #ifndef IPV6_ROUTER_LIST_SIZE #define IPV6_ROUTER_LIST_SIZE 2 #elif (IPV6_ROUTER_LIST_SIZE < 1) #error IPV6_ROUTER_LIST_SIZE parameter is not valid #endif //Maximum number of DNS servers #ifndef IPV6_DNS_SERVER_LIST_SIZE #define IPV6_DNS_SERVER_LIST_SIZE 2 #elif (IPV6_DNS_SERVER_LIST_SIZE < 1) #error IPV6_DNS_SERVER_LIST_SIZE parameter is not valid #endif //Size of the IPv6 multicast filter #ifndef IPV6_MULTICAST_FILTER_SIZE #define IPV6_MULTICAST_FILTER_SIZE 8 #elif (IPV6_MULTICAST_FILTER_SIZE < 1) #error IPV6_MULTICAST_FILTER_SIZE parameter is not valid #endif //Version number for IPv6 #define IPV6_VERSION 6 //Minimum MTU that routers and physical links are required to handle #define IPV6_DEFAULT_MTU 1280 //Macro used for defining an IPv6 address #define IPV6_ADDR(a, b, c, d, e, f, g, h) {{{ \ MSB(a), LSB(a), MSB(b), LSB(b), MSB(c), LSB(c), MSB(d), LSB(d), \ MSB(e), LSB(e), MSB(f), LSB(f), MSB(g), LSB(g), MSB(h), LSB(h)}}} //Copy IPv6 address #define ipv6CopyAddr(destIpAddr, srcIpAddr) \ memcpy(destIpAddr, srcIpAddr, sizeof(Ipv6Addr)) //Compare IPv6 addresses #define ipv6CompAddr(ipAddr1, ipAddr2) \ (!memcmp(ipAddr1, ipAddr2, sizeof(Ipv6Addr))) //Determine whether an IPv6 address is a link-local unicast address #define ipv6IsLinkLocalUnicastAddr(ipAddr) \ ((ipAddr)->b[0] == 0xFE && ((ipAddr)->b[1] & 0xC0) == 0x80) //Determine whether an IPv6 address is a site-local unicast address #define ipv6IsSiteLocalUnicastAddr(ipAddr) \ ((ipAddr)->b[0] == 0xFE && ((ipAddr)->b[1] & 0xC0) == 0xC0) //Determine whether an IPv6 address is a multicast address #define ipv6IsMulticastAddr(ipAddr) \ ((ipAddr)->b[0] == 0xFF) //Determine whether an IPv6 address is a solicited-node address #define ipv6IsSolicitedNodeAddr(ipAddr) \ ipv6CompPrefix(ipAddr, &IPV6_SOLICITED_NODE_ADDR_PREFIX, 104) //Get the state of the link-local address #define ipv6GetLinkLocalAddrState(interface) \ (interface->ipv6Context.addrList[0].state) /** * @brief IPv6 address scopes **/ typedef enum { IPV6_ADDR_SCOPE_INTERFACE_LOCAL = 1, IPV6_ADDR_SCOPE_LINK_LOCAL = 2, IPV6_ADDR_SCOPE_ADMIN_LOCAL = 4, IPV6_ADDR_SCOPE_SITE_LOCAL = 5, IPV6_ADDR_SCOPE_ORGANIZATION_LOCAL = 8, IPV6_ADDR_SCOPE_GLOBAL = 14 } Ipv6AddrScope; /** * @brief IPv6 address state **/ typedef enum { IPV6_ADDR_STATE_INVALID = 0, ///<An address that is not assigned to any interface IPV6_ADDR_STATE_TENTATIVE = 1, ///<An address whose uniqueness on a link is being verified IPV6_ADDR_STATE_PREFERRED = 2, ///<An address assigned to an interface whose use is unrestricted IPV6_ADDR_STATE_DEPRECATED = 3 ///<An address assigned to an interface whose use is discouraged } Ipv6AddrState; /** * @brief IPv6 Next Header types **/ typedef enum { IPV6_HOP_BY_HOP_OPT_HEADER = 0, IPV6_TCP_HEADER = 6, IPV6_UDP_HEADER = 17, IPV6_ROUTING_HEADER = 43, IPV6_FRAGMENT_HEADER = 44, IPV6_ESP_HEADER = 50, IPV6_AUTH_HEADER = 51, IPV6_ICMPV6_HEADER = 58, IPV6_NO_NEXT_HEADER = 59, IPV6_DEST_OPT_HEADER = 60 } Ipv6NextHeaderType; /** * @brief IPv6 fragment offset field **/ typedef enum { IPV6_OFFSET_MASK = 0xFFF8, IPV6_FLAG_RES1 = 0x0004, IPV6_FLAG_RES2 = 0x0002, IPV6_FLAG_M = 0x0001 } Ipv6FragmentOffset; /** * @brief IPv6 option types **/ typedef enum { IPV6_OPTION_TYPE_MASK = 0x1F, IPV6_OPTION_TYPE_PAD1 = 0x00, IPV6_OPTION_TYPE_PADN = 0x01 } Ipv6OptionType; /** * @brief Actions to be taken for unrecognized options **/ typedef enum { IPV6_ACTION_MASK = 0xC0, IPV6_ACTION_SKIP_OPTION = 0x00, IPV6_ACTION_DISCARD_PACKET = 0x40, IPV6_ACTION_SEND_ICMP_ERROR_ALL = 0x80, IPV6_ACTION_SEND_ICMP_ERROR_UNI = 0xC0 } Ipv6Actions; //CodeWarrior or Win32 compiler? #if defined(__CWCC__) || defined(_WIN32) #pragma pack(push, 1) #endif /** * @brief IPv6 network address **/ typedef __start_packed struct { __start_packed union { uint8_t b[16]; uint16_t w[8]; uint32_t dw[4]; }; } __end_packed Ipv6Addr; /** * @brief IPv6 header **/ __start_packed struct _Ipv6Header { #ifdef _CPU_BIG_ENDIAN uint8_t version : 4; //0 uint8_t trafficClassH : 4; uint8_t trafficClassL : 4; //1 uint8_t flowLabelH : 4; #else uint8_t trafficClassH : 4; //0 uint8_t version : 4; uint8_t flowLabelH : 4; //1 uint8_t trafficClassL : 4; #endif uint16_t flowLabelL; //2-3 uint16_t payloadLength; //4-5 uint8_t nextHeader; //6 uint8_t hopLimit; //7 Ipv6Addr srcAddr; //8-23 Ipv6Addr destAddr; //24-39 uint8_t payload[]; //40 } __end_packed; /** * @brief IPv6 Hop-by-Hop Options header **/ typedef __start_packed struct { uint8_t nextHeader; //0 uint8_t hdrExtLen; //1 uint8_t options[]; //2 } __end_packed Ipv6HopByHopOptHeader; /** * @brief IPv6 Destination Options header **/ typedef __start_packed struct { uint8_t nextHeader; //0 uint8_t hdrExtLen; //1 uint8_t options[]; //2 } __end_packed Ipv6DestOptHeader; /** * @brief IPv6 Type 0 Routing header **/ typedef __start_packed struct { uint8_t nextHeader; //0 uint8_t hdrExtLen; //1 uint8_t routingType; //2 uint8_t segmentsLeft; //3 uint32_t reserved; //4-7 Ipv6Addr address[]; //8 } __end_packed Ipv6RoutingHeader; /** * @brief IPv6 Fragment header **/ __start_packed struct _Ipv6FragmentHeader { uint8_t nextHeader; //0 uint8_t reserved; //1 uint16_t fragmentOffset; //2-3 uint32_t identification; //4-7 } __end_packed; /** * @brief IPv6 Authentication header **/ typedef __start_packed struct { uint8_t nextHeader; //0 uint8_t payloadLength; //1 uint16_t reserved; //2-3 uint32_t securityParamIndex; //4-7 uint32_t sequenceNumber; //8-11 uint8_t authData[]; //12 } __end_packed Ipv6AuthHeader; /** * @brief IPv6 Encapsulating Security Payload header **/ typedef __start_packed struct { uint32_t securityParamIndex; //0-3 uint32_t sequenceNumber; //4-7 uint8_t payloadData[]; //8 } __end_packed Ipv6EspHeader; /** * @brief IPv6 option **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint8_t data[]; //2 } __end_packed Ipv6Option; /** * @brief IPv6 pseudo header **/ __start_packed struct _Ipv6PseudoHeader { Ipv6Addr srcAddr; //0-15 Ipv6Addr destAddr; //16-31 uint32_t length; //32-35 uint32_t reserved : 24; //36-38 uint32_t nextHeader : 8; //39 } __end_packed; //CodeWarrior or Win32 compiler? #if defined(__CWCC__) || defined(_WIN32) #pragma pack(pop) #endif /** * @brief IPv6 address entry **/ typedef struct { Ipv6Addr addr; ///<IPv6 address Ipv6AddrState state; ///<IPv6 address state bool_t duplicate; ///<The address is a duplicate systime_t validLifetime; ///<Valid lifetime systime_t preferredLifetime; ///<Preferred lifetime bool_t permanent; ///<Permanently assigned address systime_t timestamp; ///<Timestamp to manage entry lifetime systime_t dadTimeout; ///<Timeout value for Duplicate Address Detection uint_t dadRetransmitCount; ///<Retransmission counter for Duplicate Address Detection } Ipv6AddrEntry; /** * @brief Prefix list entry **/ typedef struct { Ipv6Addr prefix; ///<IPv6 prefix information uint8_t prefixLength; ///<IPv6 prefix length systime_t validLifetime; ///<Valid lifetime systime_t preferredLifetime; ///<Preferred lifetime bool_t permanent; ///<Permanently assigned prefix systime_t timestamp; ///<Timestamp to manage entry lifetime } Ipv6PrefixEntry; /** * @brief Default router list entry **/ typedef struct { Ipv6Addr addr; ///<Router address systime_t lifetime; ///<Router lifetime bool_t permanent; ///<Permanently assigned router systime_t timestamp; ///<Timestamp to manage entry lifetime } Ipv6RouterEntry; /** * @brief IPv6 multicast filter entry **/ typedef struct { Ipv6Addr addr; ///<Multicast address uint_t refCount; ///<Reference count for the current entry uint_t state; ///<MLD node state bool_t flag; ///<MLD flag systime_t timer; ///<Delay timer } Ipv6FilterEntry; /** * @brief IPv6 context **/ typedef struct { size_t linkMtu; ///<Maximum transmission unit bool_t isRouter; ///<A flag indicating whether routing is enabled on this interface uint8_t curHopLimit; ///<Default value for the Hop Limit field bool_t enableMulticastEchoReq; ///<Support for multicast ICMPv6 Echo Request messages Ipv6AddrEntry addrList[IPV6_ADDR_LIST_SIZE]; ///<IPv6 unicast address list Ipv6Addr anycastAddrList[IPV6_ANYCAST_ADDR_LIST_SIZE]; ///<IPv6 anycast address list Ipv6PrefixEntry prefixList[IPV6_PREFIX_LIST_SIZE]; ///<Prefix list Ipv6RouterEntry routerList[IPV6_ROUTER_LIST_SIZE]; ///<Default router list Ipv6Addr dnsServerList[IPV6_DNS_SERVER_LIST_SIZE]; ///<DNS servers Ipv6FilterEntry multicastFilter[IPV6_MULTICAST_FILTER_SIZE]; ///<Multicast filter table #if (IPV6_FRAG_SUPPORT == ENABLED) uint32_t identification; ///<IPv6 fragment identification field Ipv6FragDesc fragQueue[IPV6_MAX_FRAG_DATAGRAMS]; ///<IPv6 fragment reassembly queue #endif } Ipv6Context; //IPv6 related constants extern const Ipv6Addr IPV6_UNSPECIFIED_ADDR; extern const Ipv6Addr IPV6_LOOPBACK_ADDR; extern const Ipv6Addr IPV6_LINK_LOCAL_ALL_NODES_ADDR; extern const Ipv6Addr IPV6_LINK_LOCAL_ALL_ROUTERS_ADDR; extern const Ipv6Addr IPV6_LINK_LOCAL_ADDR_PREFIX; extern const Ipv6Addr IPV6_SOLICITED_NODE_ADDR_PREFIX; //IPv6 related functions error_t ipv6Init(NetInterface *interface); error_t ipv6SetMtu(NetInterface *interface, size_t mtu); error_t ipv6GetMtu(NetInterface *interface, size_t *mtu); error_t ipv6SetLinkLocalAddr(NetInterface *interface, const Ipv6Addr *addr); error_t ipv6GetLinkLocalAddr(NetInterface *interface, Ipv6Addr *addr); error_t ipv6SetGlobalAddr(NetInterface *interface, uint_t index, const Ipv6Addr *addr); error_t ipv6GetGlobalAddr(NetInterface *interface, uint_t index, Ipv6Addr *addr); error_t ipv6SetAnycastAddr(NetInterface *interface, uint_t index, const Ipv6Addr *addr); error_t ipv6GetAnycastAddr(NetInterface *interface, uint_t index, Ipv6Addr *addr); error_t ipv6SetPrefix(NetInterface *interface, uint_t index, const Ipv6Addr *prefix, uint_t length); error_t ipv6GetPrefix(NetInterface *interface, uint_t index, Ipv6Addr *prefix, uint_t *length); error_t ipv6SetDefaultRouter(NetInterface *interface, uint_t index, const Ipv6Addr *addr); error_t ipv6GetDefaultRouter(NetInterface *interface, uint_t index, Ipv6Addr *addr); error_t ipv6SetDnsServer(NetInterface *interface, uint_t index, const Ipv6Addr *addr); error_t ipv6GetDnsServer(NetInterface *interface, uint_t index, Ipv6Addr *addr); void ipv6LinkChangeEvent(NetInterface *interface); void ipv6ProcessPacket(NetInterface *interface, NetBuffer *ipPacket, size_t ipPacketOffset); error_t ipv6ParseHopByHopOptHeader(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset); error_t ipv6ParseDestOptHeader(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset); error_t ipv6ParseRoutingHeader(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset); error_t ipv6ParseAuthHeader(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset); error_t ipv6ParseEspHeader(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t *headerOffset, size_t *nextHeaderOffset); error_t ipv6ParseOptions(NetInterface *interface, const NetBuffer *ipPacket, size_t ipPacketOffset, size_t optOffset, size_t optLength); error_t ipv6SendDatagram(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, uint8_t hopLimit); error_t ipv6SendPacket(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, uint32_t fragId, size_t fragOffset, NetBuffer *buffer, size_t offset, uint8_t hopLimit); error_t ipv6JoinMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr); error_t ipv6LeaveMulticastGroup(NetInterface *interface, const Ipv6Addr *groupAddr); error_t ipv6StringToAddr(const char_t *str, Ipv6Addr *ipAddr); char_t *ipv6AddrToString(const Ipv6Addr *ipAddr, char_t *str); void ipv6DumpHeader(const Ipv6Header *ipHeader); #endif