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 
46 
48 {
49  static TypeId tid = TypeId ("ns3::Radvd")
51  .AddConstructor<Radvd> ()
52  .AddAttribute ("AdvertisementJitter",
53  "Uniform variable to provide jitter between min and max values of AdvInterval",
54  StringValue("ns3::UniformRandomVariable"),
55  MakePointerAccessor (&Radvd::m_jitter),
56  MakePointerChecker<UniformRandomVariable> ());
57  ;
58  return tid;
59 }
60 
62 {
63  NS_LOG_FUNCTION (this);
64 }
65 
67 {
68  NS_LOG_FUNCTION (this);
69  for (RadvdInterfaceListI it = m_configurations.begin (); it != m_configurations.end (); ++it)
70  {
71  *it = 0;
72  }
73  m_configurations.clear ();
74  m_socket = 0;
75 }
76 
78 {
79  NS_LOG_FUNCTION (this);
81 }
82 
84 {
85  NS_LOG_FUNCTION (this);
86 
87  if (!m_socket)
88  {
89  TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
91 
93 
94  /* m_socket->Bind (Inet6SocketAddress (m_localAddress, 0)); */
95  /* m_socket->Connect (Inet6SocketAddress (Ipv6Address::GetAllNodesMulticast (), 0)); */
98  }
99 
100  for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
101  {
102  m_eventIds[(*it)->GetInterface ()] = EventId ();
103  ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true);
104  }
105 }
106 
108 {
109  NS_LOG_FUNCTION (this);
110 
111  if (m_socket)
112  {
114  }
115 
116  for (EventIdMapI it = m_eventIds.begin (); it != m_eventIds.end (); ++it)
117  {
118  Simulator::Cancel ((*it).second);
119  }
120  m_eventIds.clear ();
121 }
122 
124 {
125  NS_LOG_FUNCTION (this << routerInterface);
126  m_configurations.push_back (routerInterface);
127 }
128 
129 int64_t
130 Radvd:: AssignStreams (int64_t stream)
131 {
132  NS_LOG_FUNCTION (this << stream);
133  m_jitter->SetStream (stream);
134  return 1;
135 }
136 
137 void Radvd::ScheduleTransmit (Time dt, Ptr<RadvdInterface> config, EventId& eventId, Ipv6Address dst, bool reschedule)
138 {
139  NS_LOG_FUNCTION (this << dt << config << &eventId << dst << reschedule);
140  eventId = Simulator::Schedule (dt, &Radvd::Send, this, config, dst, reschedule);
141 }
142 
143 void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule)
144 {
145  NS_LOG_FUNCTION (this << dst << reschedule);
146  NS_ASSERT (m_eventIds[config->GetInterface ()].IsExpired ());
147  Icmpv6RA raHdr;
149  Icmpv6OptionMtu mtuHdr;
151 
152  if (m_eventIds.size () == 0)
153  {
154  return;
155  }
156 
157  std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes ();
158  Ptr<Packet> p = Create<Packet> ();
159  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
160 
161  /* set RA header information */
162  raHdr.SetFlagM (config->IsManagedFlag ());
163  raHdr.SetFlagO (config->IsOtherConfigFlag ());
164  raHdr.SetFlagH (config->IsHomeAgentFlag ());
165  raHdr.SetCurHopLimit (config->GetCurHopLimit ());
166  raHdr.SetLifeTime (config->GetDefaultLifeTime ());
167  raHdr.SetReachableTime (config->GetReachableTime ());
168  raHdr.SetRetransmissionTime (config->GetRetransTimer ());
169 
170  if (config->IsSourceLLAddress ())
171  {
172  /* Get L2 address from NetDevice */
173  Address addr = ipv6->GetNetDevice (config->GetInterface ())->GetAddress ();
174  llaHdr = Icmpv6OptionLinkLayerAddress (true, addr);
175  p->AddHeader (llaHdr);
176  }
177 
178  if (config->GetLinkMtu ())
179  {
180  NS_ASSERT (config->GetLinkMtu () >= 1280);
181  mtuHdr = Icmpv6OptionMtu (config->GetLinkMtu ());
182  p->AddHeader (mtuHdr);
183  }
184 
185  /* add list of prefixes */
186  for (std::list<Ptr<RadvdPrefix> >::const_iterator jt = prefixes.begin (); jt != prefixes.end (); jt++)
187  {
188  uint8_t flags = 0;
189  prefixHdr = Icmpv6OptionPrefixInformation ();
190  prefixHdr.SetPrefix ((*jt)->GetNetwork ());
191  prefixHdr.SetPrefixLength ((*jt)->GetPrefixLength ());
192  prefixHdr.SetValidTime ((*jt)->GetValidLifeTime ());
193  prefixHdr.SetPreferredTime ((*jt)->GetPreferredLifeTime ());
194 
195  if ((*jt)->IsOnLinkFlag ())
196  {
197  flags += 1 << 7;
198  }
199 
200  if ((*jt)->IsAutonomousFlag ())
201  {
202  flags += 1 << 6;
203  }
204 
205  if ((*jt)->IsRouterAddrFlag ())
206  {
207  flags += 1 << 5;
208  }
209 
210  prefixHdr.SetFlags (flags);
211 
212  p->AddHeader (prefixHdr);
213  }
214 
215  Ipv6Address src = ipv6->GetAddress (config->GetInterface (), 0).GetAddress ();
216  m_socket->Bind (Inet6SocketAddress (src, 0));
217  m_socket->Connect (Inet6SocketAddress (dst, 0));
218 
219  /* as we know interface index that will be used to send RA and
220  * we always send RA with router's link-local address, we can
221  * calculate checksum here.
222  */
223  raHdr.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + raHdr.GetSerializedSize (), 58 /* ICMPv6 */);
224  p->AddHeader (raHdr);
225 
226  /* Router advertisements MUST always have a ttl of 255
227  * The ttl value should be set as a socket option, but this is not yet implemented
228  */
229  SocketIpTtlTag ttl;
230  ttl.SetTtl (255);
231  p->AddPacketTag (ttl);
232 
233  /* send RA */
234  NS_LOG_LOGIC ("Send RA");
235  m_socket->Send (p, 0);
236 
237  if (reschedule)
238  {
239  uint64_t delay = static_cast<uint64_t> (m_jitter->GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
240  NS_LOG_INFO ("Reschedule in " << delay);
241  Time t = MilliSeconds (delay);
242  ScheduleTransmit (t, config, m_eventIds[config->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), reschedule);
243  }
244 }
245 
247 {
248  NS_LOG_FUNCTION (this << socket);
249  Ptr<Packet> packet = 0;
250  Address from;
251 
252  while ((packet = socket->RecvFrom (from)))
253  {
255  {
256  Ipv6Header hdr;
257  Icmpv6RS rsHdr;
259  uint64_t delay = 0;
260  Time t;
261 
262  packet->RemoveHeader (hdr);
263  uint8_t type;
264  packet->CopyData (&type, sizeof(type));
265 
266  switch (type)
267  {
269  packet->RemoveHeader (rsHdr);
270  NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ());
271 
272  /* XXX advertise just prefix(es) for the interface not all */
273  for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++)
274  {
275  /* calculate minimum delay between RA */
276  delay = static_cast<uint64_t> (m_jitter->GetValue (0, MAX_RA_DELAY_TIME) + 0.5);
277  t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */
278 
279  /* if our solicited RA is before the next periodic RA, we schedule it */
280  if (t.GetTimeStep () < static_cast<int64_t> (m_eventIds[(*it)->GetInterface ()].GetTs ()))
281  {
282  NS_LOG_INFO ("schedule new RA");
283  EventId ei;
284 
285  ScheduleTransmit (MilliSeconds (delay), (*it), ei, address.GetIpv6 (), false);
286  }
287  }
288  break;
289  default:
290  break;
291  }
292  }
293  }
294 }
295 
296 } /* namespace ns3 */
297 
uint32_t RemoveHeader(Header &header)
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.
Packet header for IPv6.
Definition: ipv6-header.h:33
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
uint32_t GetLinkMtu() const
Get link MTU.
ICMPv6 Router Advertisement header.
virtual void StartApplication()
Start the application.
Definition: radvd.cc:83
RadvdInterfaceList m_configurations
List of configuration for interface.
Definition: radvd.h:144
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
Definition: radvd.h:96
void ScheduleTransmit(Time dt, Ptr< RadvdInterface > config, EventId &eventId, Ipv6Address dst=Ipv6Address::GetAllNodesMulticast(), bool reschedule=false)
Schedule sending a packet.
Definition: radvd.cc:137
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:841
ICMPv6 Router Solicitation header.
#define NS_ASSERT(condition)
Definition: assert.h:64
std::list< Ptr< RadvdInterface > >::iterator RadvdInterfaceListI
Definition: radvd.h:95
uint32_t GetRetransTimer() const
Get retransmission timer.
uint32_t GetSize(void) const
Definition: packet.h:650
#define NS_LOG_INFO(msg)
Definition: log.h:264
static void Cancel(const EventId &id)
Definition: simulator.cc:268
Callback< R > MakeNullCallback(void)
Definition: callback.h:1395
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
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:869
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)
Definition: radvd.cc:130
virtual ~Radvd()
Destructor.
Definition: radvd.cc:66
void SetPreferredTime(uint32_t preferredTime)
Set the preferred time of the information.
EventIdMap m_eventIds
Event ID map.
Definition: radvd.h:149
The base class for all ns3 applications.
Definition: application.h:61
void SetTtl(uint8_t ttl)
Definition: socket.cc:582
bool IsOtherConfigFlag() const
Is &quot;other config&quot; flag enabled ?
Hold an unsigned integer type.
Definition: uinteger.h:46
void SetPrefixLength(uint8_t prefixLength)
Set the prefix length.
ICMPv6 Option Prefix Information.
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
Ptr< Node > GetNode() const
Definition: application.cc:103
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:127
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
#define list
virtual void DoDispose()
Dispose the instance.
Definition: radvd.cc:77
Ptr< Socket > m_socket
Raw socket to send RA.
Definition: radvd.h:139
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:246
virtual void DoDispose(void)
Definition: application.cc:82
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.
ICMPv6 MTU option.
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
Definition: radvd.h:99
static Ipv6Address GetAllNodesMulticast()
Get the &quot;all nodes multicast&quot; address.
int64_t GetTimeStep(void) const
Definition: nstime.h:314
static Time Now(void)
Definition: simulator.cc:180
void Send(Ptr< RadvdInterface > config, Ipv6Address dst=Ipv6Address::GetAllNodesMulticast(), bool reschedule=false)
Send a packet.
Definition: radvd.cc:143
virtual void StopApplication()
Stop the application.
Definition: radvd.cc:107
void SetFlags(uint8_t flags)
Set the flags.
Describes an IPv6 address.
Definition: ipv6-address.h:46
NS_LOG_COMPONENT_DEFINE("PacketLossCounter")
Radvd()
Constructor.
Definition: radvd.cc:61
void AddConfiguration(Ptr< RadvdInterface > routerInterface)
Add configuration for an interface;.
Definition: radvd.cc:123
an identifier for simulation events.
Definition: event-id.h:46
Ptr< UniformRandomVariable > m_jitter
Variable to provide jitter in advertisement interval.
Definition: radvd.h:154
Ipv6Address GetSourceAddress(void) const
Get the &quot;Source address&quot; field.
Definition: ipv6-header.cc:101
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
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:47
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:160
Ptr< T > GetObject(void) const
Definition: object.h:360
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
void SetPrefix(Ipv6Address prefix)
Set the IPv6 prefix.
void AddHeader(const Header &header)
Definition: packet.cc:253
uint32_t GetReachableTime() const
Get reachable time.
bool IsHomeAgentFlag() const
Is &quot;home agent&quot; flag enabled ?
static TypeId LookupByName(std::string name)
Definition: type-id.cc:535