Webserver+3d print
cyclone_tcp/ipv6/ndp.h
- Committer:
- Sergunb
- Date:
- 2017-02-04
- Revision:
- 0:8918a71cdbe9
File content as of revision 0:8918a71cdbe9:
/** * @file ndp.h * @brief NDP (Neighbor Discovery Protocol) * * @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 _NDP_H #define _NDP_H //Dependencies #include "core/net.h" //NDP support #ifndef NDP_SUPPORT #define NDP_SUPPORT ENABLED #elif (NDP_SUPPORT != ENABLED && NDP_SUPPORT != DISABLED) #error NDP_SUPPORT parameter is not valid #endif //NDP tick interval #ifndef NDP_TICK_INTERVAL #define NDP_TICK_INTERVAL 200 #elif (NDP_TICK_INTERVAL < 10) #error NDP_TICK_INTERVAL parameter is not valid #endif //Neighbor cache size #ifndef NDP_NEIGHBOR_CACHE_SIZE #define NDP_NEIGHBOR_CACHE_SIZE 8 #elif (NDP_NEIGHBOR_CACHE_SIZE < 1) #error NDP_NEIGHBOR_CACHE_SIZE parameter is not valid #endif //Destination cache size #ifndef NDP_DEST_CACHE_SIZE #define NDP_DEST_CACHE_SIZE 8 #elif (NDP_DEST_CACHE_SIZE < 1) #error NDP_DEST_CACHE_SIZE parameter is not valid #endif //Maximum number of packets waiting for address resolution to complete #ifndef NDP_MAX_PENDING_PACKETS #define NDP_MAX_PENDING_PACKETS 2 #elif (NDP_MAX_PENDING_PACKETS < 1) #error NDP_MAX_PENDING_PACKETS parameter is not valid #endif //Maximum time interval between Router Advertisements #ifndef NDP_MAX_RTR_ADVERT_INTERVAL #define NDP_MAX_RTR_ADVERT_INTERVAL 600000 #elif (NDP_MAX_RTR_ADVERT_INTERVAL < 1000) #error NDP_MAX_RTR_ADVERT_INTERVAL parameter is not valid #endif //Maximum time interval between initial Router Advertisements #ifndef NDP_MAX_INITIAL_RTR_ADVERT_INTERVAL #define NDP_MAX_INITIAL_RTR_ADVERT_INTERVAL 16000 #elif (NDP_MAX_INITIAL_RTR_ADVERT_INTERVAL < 1000) #error NDP_MAX_INITIAL_RTR_ADVERT_INTERVAL parameter is not valid #endif //Maximum number of initial Router Advertisements #ifndef NDP_MAX_INITIAL_RTR_ADVERTISEMENTS #define NDP_MAX_INITIAL_RTR_ADVERTISEMENTS 3 #elif (NDP_MAX_INITIAL_RTR_ADVERTISEMENTS < 1) #error NDP_MAX_INITIAL_RTR_ADVERTISEMENTS parameter is not valid #endif //Maximum number of final Router Advertisements #ifndef NDP_MAX_FINAL_RTR_ADVERTISEMENTS #define NDP_MAX_FINAL_RTR_ADVERTISEMENTS 3 #elif (NDP_MAX_FINAL_RTR_ADVERTISEMENTS < 1) #error NDP_MAX_FINAL_RTR_ADVERTISEMENTS parameter is not valid #endif //Minimum delay between Router Advertisements #ifndef NDP_MIN_DELAY_BETWEEN_RAS #define NDP_MIN_DELAY_BETWEEN_RAS 3000 #elif (NDP_MIN_DELAY_BETWEEN_RAS < 1000) #error NDP_MIN_DELAY_BETWEEN_RAS parameter is not valid #endif //Maximum delay for Router Advertisements sent in response to a Router Solicitation #ifndef NDP_MAX_RA_DELAY_TIME #define NDP_MAX_RA_DELAY_TIME 500 #elif (NDP_MAX_RA_DELAY_TIME < 100) #error NDP_MAX_RA_DELAY_TIME parameter is not valid #endif //Minimum delay before transmitting the first Router Solicitation message #ifndef NDP_MIN_RTR_SOLICITATION_DELAY #define NDP_MIN_RTR_SOLICITATION_DELAY 0 #elif (NDP_MIN_RTR_SOLICITATION_DELAY < 0) #error NDP_MIN_RTR_SOLICITATION_DELAY parameter is not valid #endif //Maximum delay before transmitting the first Router Solicitation message #ifndef NDP_MAX_RTR_SOLICITATION_DELAY #define NDP_MAX_RTR_SOLICITATION_DELAY 1000 #elif (NDP_MAX_RTR_SOLICITATION_DELAY < 0) #error NDP_MAX_RTR_SOLICITATION_DELAY parameter is not valid #endif //The time between retransmissions of Router Solicitation messages #ifndef NDP_RTR_SOLICITATION_INTERVAL #define NDP_RTR_SOLICITATION_INTERVAL 4000 #elif (NDP_RTR_SOLICITATION_INTERVAL < 1000) #error NDP_RTR_SOLICITATION_INTERVAL parameter is not valid #endif //Number of retransmissions for Router Solicitation messages #ifndef NDP_MAX_RTR_SOLICITATIONS #define NDP_MAX_RTR_SOLICITATIONS 3 #elif (NDP_MAX_RTR_SOLICITATIONS < 1) #error NDP_MAX_RTR_SOLICITATIONS parameter is not valid #endif //Number of retransmissions for multicast Neighbor Solicitation messages #ifndef NDP_MAX_MULTICAST_SOLICIT #define NDP_MAX_MULTICAST_SOLICIT 3 #elif (NDP_MAX_MULTICAST_SOLICIT < 1) #error NDP_MAX_MULTICAST_SOLICIT parameter is not valid #endif //Number of retransmissions for unicast Neighbor Solicitation messages #ifndef NDP_MAX_UNICAST_SOLICIT #define NDP_MAX_UNICAST_SOLICIT 3 #elif (NDP_MAX_UNICAST_SOLICIT < 1) #error NDP_MAX_UNICAST_SOLICIT parameter is not valid #endif //Maximum number of Neighbor Solicitation messages sent while performing DAD #ifndef NDP_DUP_ADDR_DETECT_TRANSMITS #define NDP_DUP_ADDR_DETECT_TRANSMITS 1 #elif (NDP_DUP_ADDR_DETECT_TRANSMITS < 0) #error NDP_DUP_ADDR_DETECT_TRANSMITS parameter is not valid #endif //Delay before sending Neighbor Advertisements if the target address is an anycast address #ifndef NDP_MAX_ANYCAST_DELAY_TIME #define NDP_MAX_ANYCAST_DELAY_TIME 1000 #elif (NDP_MAX_ANYCAST_DELAY_TIME < 100) #error NDP_MAX_ANYCAST_DELAY_TIME parameter is not valid #endif //Maximum number of unsolicited Neighbor Advertisements #ifndef NDP_MAX_NEIGHBOR_ADVERTISEMENT #define NDP_MAX_NEIGHBOR_ADVERTISEMENT 3 #elif (NDP_MAX_NEIGHBOR_ADVERTISEMENT < 0) #error NDP_MAX_NEIGHBOR_ADVERTISEMENT parameter is not valid #endif //The time a neighbor is considered reachable after receiving a reachability confirmation #ifndef NDP_REACHABLE_TIME #define NDP_REACHABLE_TIME 30000 #elif (NDP_REACHABLE_TIME < 1000) #error NDP_REACHABLE_TIME parameter is not valid #endif //The time between retransmissions of Neighbor Solicitation messages #ifndef NDP_RETRANS_TIMER #define NDP_RETRANS_TIMER 1000 #elif (NDP_RETRANS_TIMER < 100) #error NDP_RETRANS_TIMER parameter is not valid #endif //Delay before sending the first probe #ifndef NDP_DELAY_FIRST_PROBE_TIME #define NDP_DELAY_FIRST_PROBE_TIME 5000 #elif (NDP_DELAY_FIRST_PROBE_TIME < 1000) #error NDP_DELAY_FIRST_PROBE_TIME parameter is not valid #endif //Hop Limit used by NDP messages #define NDP_HOP_LIMIT 255 //Infinite lifetime #define NDP_INFINITE_LIFETIME 0xFFFFFFFF /** * @brief Neighbor Discovery options **/ typedef enum { NDP_OPT_SOURCE_LINK_LAYER_ADDR = 1, NDP_OPT_TARGET_LINK_LAYER_ADDR = 2, NDP_OPT_PREFIX_INFORMATION = 3, NDP_OPT_REDIRECTED_HEADER = 4, NDP_OPT_MTU = 5, NDP_OPT_ROUTE_INFORMATION = 24, NDP_OPT_RECURSIVE_DNS_SERVER = 25, NDP_OPT_DNS_SEARCH_LIST = 31, NDP_OPT_6LOWPAN_CONTEXT = 34, NDP_OPT_ANY = 255 } NdpOptionType; /** * @brief Router selection preferences **/ typedef enum { NDP_ROUTER_SEL_PREFERENCE_MEDIUM = 0, NDP_ROUTER_SEL_PREFERENCE_HIGH = 1, NDP_ROUTER_SEL_PREFERENCE_RESERVED = 2, NDP_ROUTER_SEL_PREFERENCE_LOW = 3 } NdpRouterSelPreference; /** * @brief Neighbor cache entry states **/ typedef enum { NDP_STATE_NONE = 0, NDP_STATE_INCOMPLETE = 1, NDP_STATE_REACHABLE = 2, NDP_STATE_STALE = 3, NDP_STATE_DELAY = 4, NDP_STATE_PROBE = 5, NDP_STATE_PERMANENT = 6 } NdpState; //CodeWarrior or Win32 compiler? #if defined(__CWCC__) || defined(_WIN32) #pragma pack(push, 1) #endif /** * @brief Router Solicitation message **/ typedef __start_packed struct { uint8_t type; //0 uint8_t code; //1 uint16_t checksum; //2-3 uint32_t reserved; //4-7 uint8_t options[]; //8 } __end_packed NdpRouterSolMessage; /** * @brief Router Advertisement message **/ typedef __start_packed struct { uint8_t type; //0 uint8_t code; //1 uint16_t checksum; //2-3 uint8_t curHopLimit; //4 #ifdef _CPU_BIG_ENDIAN uint8_t m : 1; //5 uint8_t o : 1; uint8_t h : 1; uint8_t prf : 2; uint8_t p : 1; uint8_t reserved : 2; #else uint8_t reserved : 2; //5 uint8_t p : 1; uint8_t prf : 2; uint8_t h : 1; uint8_t o : 1; uint8_t m : 1; #endif uint16_t routerLifetime; //6-7 uint32_t reachableTime; //8-11 uint32_t retransTimer; //12-15 uint8_t options[]; //16 } __end_packed NdpRouterAdvMessage; /** * @brief Neighbor Solicitation message **/ typedef __start_packed struct { uint8_t type; //0 uint8_t code; //1 uint16_t checksum; //2-3 uint32_t reserved; //4-7 Ipv6Addr targetAddr; //8-23 uint8_t options[]; //24 } __end_packed NdpNeighborSolMessage; /** * @brief Neighbor Advertisement message **/ typedef __start_packed struct { uint8_t type; //0 uint8_t code; //1 uint16_t checksum; //2-3 #ifdef _CPU_BIG_ENDIAN uint32_t r : 1; //4 uint32_t s : 1; uint32_t o : 1; uint32_t reserved1 : 5; uint32_t reserved2 : 24; //5-7 #else uint32_t reserved1 : 5; //4 uint32_t o : 1; uint32_t s : 1; uint32_t r : 1; uint32_t reserved2 : 24; //5-7 #endif Ipv6Addr targetAddr; //8-23 uint8_t options[]; //24 } __end_packed NdpNeighborAdvMessage; /** * @brief Redirect message **/ typedef __start_packed struct { uint8_t type; //0 uint8_t code; //1 uint16_t checksum; //2-3 uint32_t reserved; //4-7 Ipv6Addr targetAddr; //8-23 Ipv6Addr destAddr; //24-39 uint8_t options[]; //40 } __end_packed NdpRedirectMessage; /** * @brief Neighbor Discovery option general format **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint8_t value[]; //2 } __end_packed NdpOption; /** * @brief Source/Target Link-Layer Address option **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 MacAddr linkLayerAddr; //2-7 } __end_packed NdpLinkLayerAddrOption; /** * @brief Prefix Information option (PIO) **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint8_t prefixLength; //2 #ifdef _CPU_BIG_ENDIAN uint8_t l : 1; //3 uint8_t a : 1; uint8_t reserved1 : 6; #else uint8_t reserved1 : 6; //3 uint8_t a : 1; uint8_t l : 1; #endif uint32_t validLifetime; //4-7 uint32_t preferredLifetime; //8-11 uint32_t reserved2; //12-15 Ipv6Addr prefix; //16-31 } __end_packed NdpPrefixInfoOption; /** * @brief Redirected Header option (RHO) **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint16_t reserved1; //2-3 uint32_t reserved2; //4-7 uint8_t ipPacket[]; //8 } __end_packed NdpRedirectedHeaderOption; /** * @brief MTU option **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint16_t reserved; //2-3 uint32_t mtu; //4-7 } __end_packed NdpMtuOption; /** * @brief Route Information option (RIO) **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint8_t prefixLength; //2 #ifdef _CPU_BIG_ENDIAN uint8_t reserved1 : 3; //3 uint8_t prf : 2; uint8_t reserved2 : 3; #else uint8_t reserved2 : 3; //3 uint8_t prf : 2; uint8_t reserved1 : 3; #endif uint32_t routeLifetime; //4-7 Ipv6Addr prefix; //8 } __end_packed NdpRouteInfoOption; /** * @brief Recursive DNS Server option (RDNSS) **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint16_t reserved; //2-3 uint32_t lifetime; //4-7 Ipv6Addr address[]; //8 } __end_packed NdpRdnssOption; /** * @brief DNS Search List option (DNSSL) **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint16_t reserved; //2-3 uint32_t lifetime; //4-7 uint8_t domainNames[]; //8 } __end_packed NdpDnsslOption; /** * @brief 6LoWPAN Context option (6CO) **/ typedef __start_packed struct { uint8_t type; //0 uint8_t length; //1 uint8_t contextLength; //2 #ifdef _CPU_BIG_ENDIAN uint8_t reserved1 : 3; //3 uint8_t c : 1; uint8_t cid : 4; #else uint8_t cid : 4; //3 uint8_t c : 1; uint8_t reserved1 : 3; #endif uint16_t reserved2; //4-5 uint16_t validLifetime; //6-7 Ipv6Addr contextPrefix; //8 } __end_packed NdpContextOption; //CodeWarrior or Win32 compiler? #if defined(__CWCC__) || defined(_WIN32) #pragma pack(pop) #endif /** * @brief NDP queue item **/ typedef struct { NetInterface *srcInterface; //<Interface from which the packet has been received NetBuffer *buffer; ///<Packet waiting for address resolution size_t offset; ///<Offset to the first byte of the packet } NdpQueueItem; /** * @brief Neighbor cache entry **/ typedef struct { NdpState state; ///<Reachability state Ipv6Addr ipAddr; ///<Unicast IPv6 address MacAddr macAddr; ///<Link layer address associated with the IPv6 address bool_t isRouter; ///<A flag indicating whether the neighbor is a router or a host systime_t timestamp; ///<Timestamp to manage entry lifetime systime_t timeout; ///<Timeout value uint_t retransmitCount; ///<Retransmission counter NdpQueueItem queue[NDP_MAX_PENDING_PACKETS]; ///<Packets waiting for address resolution to complete uint_t queueSize; ///<Number of queued packets } NdpNeighborCacheEntry; /** * @brief Destination cache entry **/ typedef struct { Ipv6Addr destAddr; ///<Destination IPv6 address Ipv6Addr nextHop; ///<IPv6 address of the next-hop neighbor size_t pathMtu; ///<Path MTU systime_t timestamp; ///<Timestamp to manage entry lifetime } NdpDestCacheEntry; /** * @brief NDP context **/ typedef struct { uint32_t reachableTime; ///<The time a node assumes a neighbor is reachable uint32_t retransTimer; ///<The time between retransmissions of NS messages uint_t dupAddrDetectTransmits; ///<Maximum number of NS messages sent while performing DAD systime_t minRtrSolicitationDelay; ///<Minimum delay before transmitting the first RS message systime_t maxRtrSolicitationDelay; ///<Maximum delay before transmitting the first RS message systime_t rtrSolicitationInterval; ///<Time interval between retransmissions of RS messages uint_t maxRtrSolicitations; ///<Number of retransmissions for RS messages uint_t rtrSolicitationCount; ///<Retransmission counter for RS messages bool_t rtrAdvReceived; ///<Valid RA message received systime_t timestamp; ///<Timestamp to manage retransmissions systime_t timeout; ///<Timeout value NdpNeighborCacheEntry neighborCache[NDP_NEIGHBOR_CACHE_SIZE]; ///<Neighbor cache NdpDestCacheEntry destCache[NDP_DEST_CACHE_SIZE]; ///<Destination cache } NdpContext; //Tick counter to handle periodic operations extern systime_t ndpTickCounter; //NDP related functions error_t ndpInit(NetInterface *interface); error_t ndpResolve(NetInterface *interface, const Ipv6Addr *ipAddr, MacAddr *macAddr); error_t ndpEnqueuePacket(NetInterface *srcInterface, NetInterface *destInterface, const Ipv6Addr *ipAddr, NetBuffer *buffer, size_t offset); void ndpTick(NetInterface *interface); void ndpLinkChangeEvent(NetInterface *interface); void ndpProcessRouterAdv(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset, uint8_t hopLimit); void ndpProcessNeighborSol(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset, uint8_t hopLimit); void ndpProcessNeighborAdv(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset, uint8_t hopLimit); void ndpProcessRedirect(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset, uint8_t hopLimit); error_t ndpSendRouterSol(NetInterface *interface); error_t ndpSendNeighborSol(NetInterface *interface, const Ipv6Addr *targetIpAddr, bool_t multicast); error_t ndpSendNeighborAdv(NetInterface *interface, const Ipv6Addr *targetIpAddr, const Ipv6Addr *destIpAddr); error_t ndpSendRedirect(NetInterface *interface, const Ipv6Addr *targetAddr, const NetBuffer *ipPacket, size_t ipPacketOffset); void ndpDumpRouterSolMessage(const NdpRouterSolMessage *message); void ndpDumpRouterAdvMessage(const NdpRouterAdvMessage *message); void ndpDumpNeighborSolMessage(const NdpNeighborSolMessage *message); void ndpDumpNeighborAdvMessage(const NdpNeighborAdvMessage *message); void ndpDumpRedirectMessage(const NdpRedirectMessage *message); #endif