Webserver+3d print

Dependents:   Nucleo

Revision:
0:8918a71cdbe9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cyclone_tcp/ipv6/ndp.h	Sat Feb 04 18:15:49 2017 +0000
@@ -0,0 +1,627 @@
+/**
+ * @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
+