A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
radvd.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2008 Telecom Bretagne
4  * Copyright (c) 2009 Strasbourg University
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
20  * Mehdi Benamor <benamor.mehdi@ensi.rnu.tn>
21  */
22 
23 #include "ns3/log.h"
24 #include "ns3/ipv6-address.h"
25 #include "ns3/nstime.h"
26 #include "ns3/simulator.h"
27 #include "ns3/packet.h"
28 #include "ns3/net-device.h"
29 #include "ns3/uinteger.h"
30 #include "ns3/inet6-socket-address.h"
31 #include "ns3/ipv6.h"
32 #include "ns3/ipv6-raw-socket-factory.h"
33 #include "ns3/ipv6-header.h"
34 #include "ns3/icmpv6-header.h"
35 #include "ns3/string.h"
36 #include "ns3/pointer.h"
37 
38 #include "radvd.h"
39 
40 namespace ns3
41 {
42 
43 NS_LOG_COMPONENT_DEFINE ("RadvdApplication")
44  ;
45 
47  ;
48 
50 {
51  static TypeId tid = TypeId ("ns3::Radvd")
53  .AddConstructor<Radvd> ()
54  .AddAttribute ("AdvertisementJitter",
55  "Uniform variable to provide jitter between min and max values of AdvInterval",
56  StringValue("ns3::UniformRandomVariable"),
57  MakePointerAccessor (&Radvd::m_jitter),
58  MakePointerChecker<UniformRandomVariable> ());
59  ;
60  return tid;
61 }
62 
64 {
65  NS_LOG_FUNCTION (this);
66 }
67 
69 {
70  NS_LOG_FUNCTION (this);
71  for (RadvdInterfaceListI it = m_configurations.begin (); it != m_configurations.end (); ++it)
72  {
73  *it = 0;
74  }
75  m_configurations.clear ();
76  m_socket = 0;
77 }
78 
80 {
81  NS_LOG_FUNCTION (this);
83 }
84 
86 {
87  NS_LOG_FUNCTION (this);
88 
89  if (!m_socket)
90  {
91  TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
93 
95 
96  /* m_socket->Bind (Inet6SocketAddress (m_localAddress, 0)); */
97  /* m_socket->Connect (Inet6SocketAddress (Ipv6Address::GetAllNodesMulticast (), 0)); */
100  }
101 
102  for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
103  {
104  m_eventIds[(*it)->GetInterface ()] = EventId ();
105  ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true);
106  }
107 }
108 
110 {
111  NS_LOG_FUNCTION (this);
112 
113  if (m_socket)
114  {
116  }
117 
118  for (EventIdMapI it = m_eventIds.begin (); it != m_eventIds.end (); ++it)
119  {
120  Simulator::Cancel ((*it).second);
121  }
122  m_eventIds.clear ();
123 }
124 
126 {
127  NS_LOG_FUNCTION (this << routerInterface);
128  m_configurations.push_back (routerInterface);
129 }
130 
131 int64_t
132 Radvd:: AssignStreams (int64_t stream)
133 {
134  NS_LOG_FUNCTION (this << stream);
135  m_jitter->SetStream (stream);
136  return 1;
137 }
138 
139 void Radvd::ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId, Ipv6Address dst, bool reschedule)
140 {
141  NS_LOG_FUNCTION (this << dt << config << &eventId << dst << reschedule);
142  eventId = Simulator::Schedule (dt, &Radvd::Send, this, config, dst, reschedule);
143 }
144 
145 void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule)
146 {
147  NS_LOG_FUNCTION (this << dst << reschedule);
148  NS_ASSERT (m_eventIds[config->GetInterface ()].IsExpired ());
149  Icmpv6RA raHdr;
151  Icmpv6OptionMtu mtuHdr;
153 
154  if (m_eventIds.size () == 0)
155  {
156  return;
157  }
158 
159  std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes ();
160  Ptr<Packet> p = Create<Packet> ();
161  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
162 
163  /* set RA header information */
164  raHdr.SetFlagM (config->IsManagedFlag ());
165  raHdr.SetFlagO (config->IsOtherConfigFlag ());
166  raHdr.SetFlagH (config->IsHomeAgentFlag ());
167  raHdr.SetCurHopLimit (config->GetCurHopLimit ());
168  raHdr.SetLifeTime (config->GetDefaultLifeTime ());
169  raHdr.SetReachableTime (config->GetReachableTime ());
170  raHdr.SetRetransmissionTime (config->GetRetransTimer ());
171 
172  if (config->IsSourceLLAddress ())
173  {
174  /* Get L2 address from NetDevice */
175  Address addr = ipv6->GetNetDevice (config->GetInterface ())->GetAddress ();
176  llaHdr = Icmpv6OptionLinkLayerAddress (true, addr);
177  p->AddHeader (llaHdr);
178  }
179 
180  if (config->GetLinkMtu ())
181  {
182  NS_ASSERT (config->GetLinkMtu () >= 1280);
183  mtuHdr = Icmpv6OptionMtu (config->GetLinkMtu ());
184  p->AddHeader (mtuHdr);
185  }
186 
187  /* add list of prefixes */
188  for (std::list<Ptr<RadvdPrefix> >::const_iterator jt = prefixes.begin (); jt != prefixes.end (); jt++)
189  {
190  uint8_t flags = 0;
191  prefixHdr = Icmpv6OptionPrefixInformation ();
192  prefixHdr.SetPrefix ((*jt)->GetNetwork ());
193  prefixHdr.SetPrefixLength ((*jt)->GetPrefixLength ());
194  prefixHdr.SetValidTime ((*jt)->GetValidLifeTime ());
195  prefixHdr.SetPreferredTime ((*jt)->GetPreferredLifeTime ());
196 
197  if ((*jt)->IsOnLinkFlag ())
198  {
199  flags += 1 << 7;
200  }
201 
202  if ((*jt)->IsAutonomousFlag ())
203  {
204  flags += 1 << 6;
205  }
206 
207  if ((*jt)->IsRouterAddrFlag ())
208  {
209  flags += 1 << 5;
210  }
211 
212  prefixHdr.SetFlags (flags);
213 
214  p->AddHeader (prefixHdr);
215  }
216 
217  Ipv6Address src = ipv6->GetAddress (config->GetInterface (), 0).GetAddress ();
218  m_socket->Bind (Inet6SocketAddress (src, 0));
219  m_socket->Connect (Inet6SocketAddress (dst, 0));
220 
221  /* as we know interface index that will be used to send RA and
222  * we always send RA with router's link-local address, we can
223  * calculate checksum here.
224  */
225  raHdr.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + raHdr.GetSerializedSize (), 58 /* ICMPv6 */);
226  p->AddHeader (raHdr);
227 
228  /* Router advertisements MUST always have a ttl of 255
229  * The ttl value should be set as a socket option, but this is not yet implemented
230  */
231  SocketIpTtlTag ttl;
232  ttl.SetTtl (255);
233  p->AddPacketTag (ttl);
234 
235  /* send RA */
236  NS_LOG_LOGIC ("Send RA");
237  m_socket->Send (p, 0);
238 
239  if (reschedule)
240  {
241  uint64_t delay = static_cast<uint64_t> (m_jitter->GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
242  NS_LOG_INFO ("Reschedule in " << delay);
243  Time t = MilliSeconds (delay);
244  ScheduleTransmit (t, config, m_eventIds[config->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), reschedule);
245  }
246 }
247 
249 {
250  NS_LOG_FUNCTION (this << socket);
251  Ptr<Packet> packet = 0;
252  Address from;
253 
254  while ((packet = socket->RecvFrom (from)))
255  {
257  {
258  Ipv6Header hdr;
259  Icmpv6RS rsHdr;
261  uint64_t delay = 0;
262  Time t;
263 
264  packet->RemoveHeader (hdr);
265  uint8_t type;
266  packet->CopyData (&type, sizeof(type));
267 
268  switch (type)
269  {
271  packet->RemoveHeader (rsHdr);
272  NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ());
273 
274  /* XXX advertise just prefix(es) for the interface not all */
275  for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
276  {
277  /* calculate minimum delay between RA */
278  delay = static_cast<uint64_t> (m_jitter->GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
279  t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */
280 
281  /* if our solicited RA is before the next periodic RA, we schedule it */
282  if (t.GetTimeStep () < static_cast<int64_t> (m_eventIds[(*it)->GetInterface ()].GetTs ()))
283  {
284  NS_LOG_INFO ("schedule new RA");
285  EventId ei;
286 
287  ScheduleTransmit (MilliSeconds (delay), (*it), ei, address.GetIpv6 (), false);
288  }
289  }
290  break;
291  default:
292  break;
293  }
294  }
295  }
296 }
297 
298 } /* namespace ns3 */
299 
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:268
RadvdPrefixList GetPrefixes() const
Get list of prefixes advertised for this interface.
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
uint32_t GetMinRtrAdvInterval() const
Get minimum RA interval.
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
uint32_t GetLinkMtu() const
Get link MTU.
Doxygen introspection did not find any typical Config paths.
virtual void StartApplication()
Start the application.
Definition: radvd.cc:85
RadvdInterfaceList m_configurations
List of configuration for interface.
Definition: radvd.h:150
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:79
hold variables of type string
Definition: string.h:19
uint32_t GetInterface() const
Get interface index for this configuration.
std::list< Ptr< RadvdInterface > >::const_iterator RadvdInterfaceListCI
Container Const Iterator: Ptr to RadvdInterface.
Definition: radvd.h:99
void ScheduleTransmit(Time dt, Ptr< RadvdInterface > config, EventId &eventId, Ipv6Address dst=Ipv6Address::GetAllNodesMulticast(), bool reschedule=false)
Schedule sending a packet.
Definition: radvd.cc:139
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:841
Doxygen introspection did not find any typical Config paths.
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
std::list< Ptr< RadvdInterface > >::iterator RadvdInterfaceListI
Container Iterator: Ptr to RadvdInterface.
Definition: radvd.h:97
uint32_t GetRetransTimer() const
Get retransmission timer.
uint32_t GetSize(void) const
Definition: packet.h:650
#define NS_LOG_INFO(msg)
Definition: log.h:298
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
Callback< R > MakeNullCallback(void)
Definition: callback.h:1395
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
uint8_t GetCurHopLimit() const
Get current hop limit.
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:996
a polymophic address class
Definition: address.h:86
bool IsManagedFlag() const
Is managed flag enabled ?
void SetValidTime(uint32_t validTime)
Set the valid time of the information.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model...
Definition: radvd.cc:132
virtual ~Radvd()
Destructor.
Definition: radvd.cc:68
void SetPreferredTime(uint32_t preferredTime)
Set the preferred time of the information.
EventIdMap m_eventIds
Event ID map.
Definition: radvd.h:155
The base class for all ns3 applications.
Definition: application.h:61
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:584
bool IsOtherConfigFlag() const
Is "other config" flag enabled ?
Hold an unsigned integer type.
Definition: uinteger.h:46
void SetPrefixLength(uint8_t prefixLength)
Set the prefix length.
Doxygen introspection did not find any typical Config paths.
Ptr< Node > GetNode() const
Definition: application.cc:104
An Inet6 address class.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
#define list
virtual void DoDispose()
Dispose the instance.
Definition: radvd.cc:79
Ptr< Socket > m_socket
Raw socket to send RA.
Definition: radvd.h:145
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
void HandleRead(Ptr< Socket > socket)
Handle received packet, especially router solicitation.
Definition: radvd.cc:248
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: application.cc:83
static const uint32_t MAX_RA_DELAY_TIME
Default value for maximum delay of RA (ms)
Definition: radvd.h:69
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Doxygen introspection did not find any typical Config paths.
uint8_t GetCode() const
Get the code field.
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
std::map< uint32_t, EventId >::iterator EventIdMapI
Container Iterator: interface number, EventId.
Definition: radvd.h:104
static Ipv6Address GetAllNodesMulticast()
Get the "all nodes multicast" address.
int64_t GetTimeStep(void) const
Definition: nstime.h:356
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void Send(Ptr< RadvdInterface > config, Ipv6Address dst=Ipv6Address::GetAllNodesMulticast(), bool reschedule=false)
Send a packet.
Definition: radvd.cc:145
virtual void StopApplication()
Stop the application.
Definition: radvd.cc:109
void SetFlags(uint8_t flags)
Set the flags.
Describes an IPv6 address.
Definition: ipv6-address.h:46
Radvd()
Constructor.
Definition: radvd.cc:63
void AddConfiguration(Ptr< RadvdInterface > routerInterface)
Add configuration for an interface;.
Definition: radvd.cc:125
an identifier for simulation events.
Definition: event-id.h:46
Ptr< UniformRandomVariable > m_jitter
Variable to provide jitter in advertisement interval.
Definition: radvd.h:160
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:102
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
static bool IsMatchingType(const Address &addr)
If the address match.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:381
uint32_t GetMaxRtrAdvInterval() const
Get maximum RA interval.
tuple address
Definition: first.py:37
uint32_t GetDefaultLifeTime() const
Get default lifetime.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
bool IsSourceLLAddress() const
Is source LLA option should be included in RA ?
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
static TypeId GetTypeId(void)
Get the type ID.
Definition: radvd.cc:49
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:161
Ptr< T > GetObject(void) const
Definition: object.h:361
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void SetPrefix(Ipv6Address prefix)
Set the IPv6 prefix.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:253
uint32_t GetReachableTime() const
Get reachable time.
bool IsHomeAgentFlag() const
Is "home agent" flag enabled ?
static TypeId LookupByName(std::string name)
Definition: type-id.cc:536