/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2007-2009 Strasbourg University * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Sebastien Vincent */ #ifndef NDISC_CACHE_H #define NDISC_CACHE_H #include #include #include "ns3/packet.h" #include "ns3/nstime.h" #include "ns3/net-device.h" #include "ns3/ipv6-address.h" #include "ns3/ptr.h" #include "ns3/timer.h" #include "ns3/sgi-hashmap.h" namespace ns3 { class NetDevice; class Ipv6Interface; /** * \class NdiscCache * \brief IPv6 Neighbor Discovery cache. */ class NdiscCache : public Object { public: class Entry; /** * \brief Get the type ID * \return type ID */ static TypeId GetTypeId (); /** * \brief Default value for unres qlen. */ static const uint32_t DEFAULT_UNRES_QLEN = 3; /** * \brief Constructor. */ NdiscCache (); /** * \brief Destructor. */ ~NdiscCache (); /** * \brief Get the NetDevice associated with this cache. * \return NetDevice */ Ptr GetDevice () const; /** * \brief Get the Ipv6Interface associated with this cache. */ Ptr GetInterface () const; /** * \brief Lookup in the cache. * \param dst destination address * \return the entry if found, 0 otherwise */ NdiscCache::Entry* Lookup (Ipv6Address dst); /** * \brief Add an entry. * \param to address to add * \return an new Entry */ NdiscCache::Entry* Add (Ipv6Address to); /** * \brief Delete an entry. * \param entry pointer to delete from the list. */ void Remove (NdiscCache::Entry* entry); /** * \brief Flush the cache. */ void Flush (); /** * \brief Set the max number of waiting packet. * \param unresQlen value to set */ void SetUnresQlen (uint32_t unresQlen); /** * \brief Get the max number of waiting packet. * \return max number */ uint32_t GetUnresQlen (); /** * \brief Set the device and interface. * \param device the device * \param interface the IPv6 interface */ void SetDevice (Ptr device, Ptr interface); /** * \class Entry * \brief A record that holds information about an NdiscCache entry. */ class Entry { public: /** * \brief Constructor. * \param nd The NdiscCache this entry belongs to. */ Entry (NdiscCache* nd); /** * \brief Changes the state to this entry to INCOMPLETE. * \param p packet that wait to be sent */ void MarkIncomplete (Ptr p); /** * \brief Changes the state to this entry to REACHABLE. * \param mac MAC address * \return the list of packet waiting */ std::list > MarkReachable (Address mac); /** * \brief Changes the state to this entry to PROBE. */ void MarkProbe (); /** * \brief Changes the state to this entry to STALE. * \param mac L2 address * \return the list of packet waiting */ std::list > MarkStale (Address mac); /** * \brief Changes the state to this entry to STALE. */ void MarkStale (); /** * \brief Changes the state to this entry to REACHABLE. */ void MarkReachable (); /** * \brief Change the state to this entry to DELAY. */ void MarkDelay (); /** * \brief Add a packet (or replace old value) in the queue. * \param p packet to add */ void AddWaitingPacket (Ptr p); /** * \brief Clear the waiting packet list. */ void ClearWaitingPacket (); /** * \brief Is the entry STALE * \return true if the entry is in STALE state, false otherwise */ bool IsStale () const; /** * \brief Is the entry REACHABLE * \return true if the entry is in REACHABLE state, false otherwise */ bool IsReachable () const; /** * \brief Is the entry DELAY * \return true if the entry is in DELAY state, false otherwise */ bool IsDelay () const; /** * \brief Is the entry INCOMPLETE * \return true if the entry is in INCOMPLETE state, false otherwise */ bool IsIncomplete () const; /** * \brief Is the entry PROBE * \return true if the entry is in PROBE state, false otherwise */ bool IsProbe () const; /** * \brief Get the MAC address of this entry. * \return the L2 address */ Address GetMacAddress () const; /** * \brief Set the MAC address of this entry. * \param mac the MAC address to set */ void SetMacAddress (Address mac); /** * \brief If the entry is a host or a router. * \return true if the node is a router, 0 if it is a host */ bool IsRouter () const; /** * \brief Set the node type. * \param router true is a router, false means a host */ void SetRouter (bool router); /** * \brief Get the number of NS retransmit. * \return number of NS that have been retransmit */ uint8_t GetNSRetransmit () const; /** * \brief Increment NS retransmit. */ void IncNSRetransmit (); /** * \brief Reset NS retransmit (=0). */ void ResetNSRetransmit (); /** * \brief Get the time of last reachability confirmation. * \return time */ Time GetLastReachabilityConfirmation () const; /** * \brief Update the time of last reachability confirmation. */ void UpdateLastReachabilityconfirmation (); /** * \brief Start the reachable timer. */ void StartReachableTimer (); /** * \brief Stop the reachable timer. */ void StopReachableTimer (); /** * \brief Start retransmit timer. */ void StartRetransmitTimer (); /** * \brief Stop retransmit timer. */ void StopRetransmitTimer (); /** * \brief Start probe timer. */ void StartProbeTimer (); /** * \brief Stop probe timer. */ void StopProbeTimer (); /** * \brief Start delay timer. */ void StartDelayTimer (); /** * \brief Stop delay timer. */ void StopDelayTimer (); /** * \brief Function called when reachable timer timeout. */ void FunctionReachableTimeout (); /** * \brief Function called when retransmit timer timeout. * It verify that the NS retransmit has reached the max so discard the entry * otherwise it retransmit a NS. */ void FunctionRetransmitTimeout (); /** * \brief Function called when probe timer timeout. */ void FunctionProbeTimeout (); /** * \brief Function called when delay timer timeout. */ void FunctionDelayTimeout (); /** * \brief Set the IPv6 address. * \param ipv6Address IPv6 address */ void SetIpv6Address (Ipv6Address ipv6Address); private: /** * \brief The IPv6 address. */ Ipv6Address m_ipv6Address; /** * \brief The Entry state enumeration. */ enum NdiscCacheEntryState_e { INCOMPLETE, /**< No mapping between IPv6 and L2 addresses */ REACHABLE, /**< Mapping exists between IPv6 and L2 addresses */ STALE, /**< Mapping is stale */ DELAY, /**< Try to wait contact from remote host */ PROBE /**< Try to contact IPv6 address to know again its L2 address */ }; /** * \brief The state of the entry. */ NdiscCacheEntryState_e m_state; /** * \brief the NdiscCache associated. */ NdiscCache* m_ndCache; /** * \brief The MAC address. */ Address m_macAddress; /** * \brief The list of packet waiting. */ std::list > m_waiting; /** * \brief Type of node (router or host). */ bool m_router; /** * \brief Reachable timer (used for NUD in REACHABLE state). */ Timer m_reachableTimer; /** * \brief Retransmission timer (used for NUD in INCOMPLETE state). */ Timer m_retransTimer; /** * \brief Probe timer (used for NUD in PROBE state). */ Timer m_probeTimer; /** * \brief Delay timer (used for NUD when in DELAY state). */ Timer m_delayTimer; /** * \brief Last time we see a reachability confirmation. */ Time m_lastReachabilityConfirmation; /** * \brief Number of NS retransmission. */ uint8_t m_nsRetransmit; }; private: typedef sgi::hash_map Cache; typedef sgi::hash_map::iterator CacheI; /** * \brief Copy constructor. * \param a cache to copy */ NdiscCache (NdiscCache const &a); /** * \brief Equal operator. * \param a cache to copy */ NdiscCache& operator= (NdiscCache const &a); /** * \brief Dispose this object. */ void DoDispose (); /** * \brief The NetDevice. */ Ptr m_device; /** * \brief the interface. */ Ptr m_interface; /** * A list of Entry. */ Cache m_ndCache; /** * \brief Max number of packet stored in m_waiting. */ uint32_t m_unresQlen; }; } /* namespace ns3 */ #endif /* NDISC_CACHE_H */