|
|
| 21 |
*/ |
21 |
*/ |
| 22 |
|
22 |
|
| 23 |
#include "ns3/log.h" |
23 |
#include "ns3/log.h" |
|
|
24 |
#include "ns3/abort.h" |
| 24 |
#include "ns3/ipv6-address.h" |
25 |
#include "ns3/ipv6-address.h" |
| 25 |
#include "ns3/nstime.h" |
26 |
#include "ns3/nstime.h" |
| 26 |
#include "ns3/simulator.h" |
27 |
#include "ns3/simulator.h" |
|
|
| 29 |
#include "ns3/uinteger.h" |
30 |
#include "ns3/uinteger.h" |
| 30 |
#include "ns3/inet6-socket-address.h" |
31 |
#include "ns3/inet6-socket-address.h" |
| 31 |
#include "ns3/ipv6.h" |
32 |
#include "ns3/ipv6.h" |
|
|
33 |
#include "ns3/ipv6-l3-protocol.h" |
| 34 |
#include "ns3/ipv6-interface.h" |
| 32 |
#include "ns3/ipv6-raw-socket-factory.h" |
35 |
#include "ns3/ipv6-raw-socket-factory.h" |
|
|
36 |
#include "ns3/ipv6-packet-info-tag.h" |
| 33 |
#include "ns3/ipv6-header.h" |
37 |
#include "ns3/ipv6-header.h" |
| 34 |
#include "ns3/icmpv6-header.h" |
38 |
#include "ns3/icmpv6-header.h" |
| 35 |
#include "ns3/string.h" |
39 |
#include "ns3/string.h" |
|
|
| 71 |
*it = 0; |
75 |
*it = 0; |
| 72 |
} |
76 |
} |
| 73 |
m_configurations.clear (); |
77 |
m_configurations.clear (); |
| 74 |
m_socket = 0; |
78 |
m_recvSocket = 0; |
| 75 |
} |
79 |
} |
| 76 |
|
80 |
|
| 77 |
void Radvd::DoDispose () |
81 |
void Radvd::DoDispose () |
| 78 |
{ |
82 |
{ |
| 79 |
NS_LOG_FUNCTION (this); |
83 |
NS_LOG_FUNCTION (this); |
|
|
84 |
|
| 85 |
m_recvSocket->Close (); |
| 86 |
m_recvSocket = 0; |
| 87 |
|
| 88 |
for (SocketMapI it = m_sendSockets.begin (); it != m_sendSockets.end (); ++it) |
| 89 |
{ |
| 90 |
it->second->Close (); |
| 91 |
it->second = 0; |
| 92 |
} |
| 93 |
|
| 80 |
Application::DoDispose (); |
94 |
Application::DoDispose (); |
| 81 |
} |
95 |
} |
| 82 |
|
96 |
|
|
|
| 84 |
{ |
98 |
{ |
| 85 |
NS_LOG_FUNCTION (this); |
99 |
NS_LOG_FUNCTION (this); |
| 86 |
|
100 |
|
| 87 |
if (!m_socket) |
101 |
TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory"); |
|
|
102 |
|
| 103 |
if (!m_recvSocket) |
| 88 |
{ |
104 |
{ |
| 89 |
TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory"); |
105 |
m_recvSocket = Socket::CreateSocket (GetNode (), tid); |
| 90 |
m_socket = Socket::CreateSocket (GetNode (), tid); |
|
|
| 91 |
|
106 |
|
| 92 |
NS_ASSERT (m_socket); |
107 |
NS_ASSERT (m_recvSocket); |
| 93 |
|
108 |
|
| 94 |
/* m_socket->Bind (Inet6SocketAddress (m_localAddress, 0)); */ |
109 |
m_recvSocket->Bind (Inet6SocketAddress (Ipv6Address::GetAllRoutersMulticast (), 0)); |
| 95 |
/* m_socket->Connect (Inet6SocketAddress (Ipv6Address::GetAllNodesMulticast (), 0)); */ |
110 |
m_recvSocket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6)); |
| 96 |
m_socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6)); |
111 |
m_recvSocket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this)); |
| 97 |
m_socket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this)); |
112 |
m_recvSocket->ShutdownSend (); |
|
|
113 |
m_recvSocket->SetRecvPktInfo (true); |
| 98 |
} |
114 |
} |
| 99 |
|
115 |
|
| 100 |
for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++) |
116 |
for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++) |
| 101 |
{ |
117 |
{ |
| 102 |
m_eventIds[(*it)->GetInterface ()] = EventId (); |
118 |
if ((*it)->IsSendAdvert ()) |
| 103 |
ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true); |
119 |
{ |
|
|
120 |
m_eventIds[(*it)->GetInterface ()] = EventId (); |
| 121 |
ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetInterface ()], Ipv6Address::GetAllNodesMulticast (), true); |
| 122 |
} |
| 123 |
|
| 124 |
Ptr<Ipv6L3Protocol> ipv6 = GetNode ()->GetObject<Ipv6L3Protocol> (); |
| 125 |
Ptr<Ipv6Interface> iFace = ipv6->GetInterface ((*it)->GetInterface ()); |
| 126 |
|
| 127 |
m_sendSockets[(*it)->GetInterface ()] = Socket::CreateSocket (GetNode (), tid); |
| 128 |
m_sendSockets[(*it)->GetInterface ()]->Bind (Inet6SocketAddress (iFace->GetLinkLocalAddress ().GetAddress (), 0)); |
| 129 |
m_sendSockets[(*it)->GetInterface ()]->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6)); |
| 130 |
m_sendSockets[(*it)->GetInterface ()]->ShutdownRecv (); |
| 104 |
} |
131 |
} |
| 105 |
} |
132 |
} |
| 106 |
|
133 |
|
|
|
| 108 |
{ |
135 |
{ |
| 109 |
NS_LOG_FUNCTION (this); |
136 |
NS_LOG_FUNCTION (this); |
| 110 |
|
137 |
|
| 111 |
if (m_socket) |
138 |
if (m_recvSocket) |
| 112 |
{ |
139 |
{ |
| 113 |
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ()); |
140 |
m_recvSocket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ()); |
| 114 |
} |
141 |
} |
| 115 |
|
142 |
|
| 116 |
for (EventIdMapI it = m_eventIds.begin (); it != m_eventIds.end (); ++it) |
143 |
for (EventIdMapI it = m_eventIds.begin (); it != m_eventIds.end (); ++it) |
|
|
| 143 |
void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule) |
170 |
void Radvd::Send (Ptr<RadvdInterface> config, Ipv6Address dst, bool reschedule) |
| 144 |
{ |
171 |
{ |
| 145 |
NS_LOG_FUNCTION (this << dst << reschedule); |
172 |
NS_LOG_FUNCTION (this << dst << reschedule); |
| 146 |
NS_ASSERT (m_eventIds[config->GetInterface ()].IsExpired ()); |
173 |
|
| 147 |
Icmpv6RA raHdr; |
174 |
Icmpv6RA raHdr; |
| 148 |
Icmpv6OptionLinkLayerAddress llaHdr; |
175 |
Icmpv6OptionLinkLayerAddress llaHdr; |
| 149 |
Icmpv6OptionMtu mtuHdr; |
176 |
Icmpv6OptionMtu mtuHdr; |
| 150 |
Icmpv6OptionPrefixInformation prefixHdr; |
177 |
Icmpv6OptionPrefixInformation prefixHdr; |
| 151 |
|
178 |
|
| 152 |
if (m_eventIds.size () == 0) |
|
|
| 153 |
{ |
| 154 |
return; |
| 155 |
} |
| 156 |
|
| 157 |
std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes (); |
179 |
std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes (); |
| 158 |
Ptr<Packet> p = Create<Packet> (); |
180 |
Ptr<Packet> p = Create<Packet> (); |
| 159 |
Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> (); |
181 |
Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> (); |
|
|
| 212 |
p->AddHeader (prefixHdr); |
234 |
p->AddHeader (prefixHdr); |
| 213 |
} |
235 |
} |
| 214 |
|
236 |
|
| 215 |
Ipv6Address src = ipv6->GetAddress (config->GetInterface (), 0).GetAddress (); |
237 |
Address sockAddr; |
| 216 |
m_socket->Bind (Inet6SocketAddress (src, 0)); |
238 |
m_sendSockets[config->GetInterface ()]->GetSockName (sockAddr); |
| 217 |
m_socket->Connect (Inet6SocketAddress (dst, 0)); |
239 |
Ipv6Address src = Inet6SocketAddress::ConvertFrom (sockAddr).GetIpv6 (); |
| 218 |
|
240 |
|
| 219 |
/* as we know interface index that will be used to send RA and |
241 |
/* 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 |
242 |
* we always send RA with router's link-local address, we can |
|
|
| 231 |
p->AddPacketTag (ttl); |
253 |
p->AddPacketTag (ttl); |
| 232 |
|
254 |
|
| 233 |
/* send RA */ |
255 |
/* send RA */ |
| 234 |
NS_LOG_LOGIC ("Send RA"); |
256 |
NS_LOG_LOGIC ("Send RA to " << dst); |
| 235 |
m_socket->Send (p, 0); |
257 |
m_sendSockets[config->GetInterface ()]->SendTo (p, 0, Inet6SocketAddress (dst, 0)); |
| 236 |
|
258 |
|
| 237 |
if (reschedule) |
259 |
if (reschedule) |
| 238 |
{ |
260 |
{ |
|
|
| 253 |
{ |
275 |
{ |
| 254 |
if (Inet6SocketAddress::IsMatchingType (from)) |
276 |
if (Inet6SocketAddress::IsMatchingType (from)) |
| 255 |
{ |
277 |
{ |
|
|
278 |
Ipv6PacketInfoTag interfaceInfo; |
| 279 |
if (!packet->RemovePacketTag (interfaceInfo)) |
| 280 |
{ |
| 281 |
NS_ABORT_MSG ("No incoming interface on RADVD message, aborting."); |
| 282 |
} |
| 283 |
uint32_t incomingIf = interfaceInfo.GetRecvIf (); |
| 284 |
Ptr<NetDevice> dev = GetNode ()->GetDevice (incomingIf); |
| 285 |
Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> (); |
| 286 |
uint32_t ipInterfaceIndex = ipv6->GetInterfaceForDevice (dev); |
| 287 |
|
| 256 |
Ipv6Header hdr; |
288 |
Ipv6Header hdr; |
| 257 |
Icmpv6RS rsHdr; |
289 |
Icmpv6RS rsHdr; |
| 258 |
Inet6SocketAddress address = Inet6SocketAddress::ConvertFrom (from); |
290 |
Inet6SocketAddress address = Inet6SocketAddress::ConvertFrom (from); |
|
|
| 269 |
packet->RemoveHeader (rsHdr); |
301 |
packet->RemoveHeader (rsHdr); |
| 270 |
NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ()); |
302 |
NS_LOG_INFO ("Received ICMPv6 Router Solicitation from " << hdr.GetSourceAddress () << " code = " << (uint32_t)rsHdr.GetCode ()); |
| 271 |
|
303 |
|
| 272 |
/* XXX advertise just prefix(es) for the interface not all */ |
|
|
| 273 |
for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++) |
304 |
for (RadvdInterfaceListCI it = m_configurations.begin (); it != m_configurations.end (); it++) |
| 274 |
{ |
305 |
{ |
| 275 |
/* calculate minimum delay between RA */ |
306 |
if (ipInterfaceIndex == (*it)->GetInterface ()) |
| 276 |
delay = static_cast<uint64_t> (m_jitter->GetValue (0, MAX_RA_DELAY_TIME) + 0.5); |
307 |
{ |
| 277 |
t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */ |
308 |
/* calculate minimum delay between RA */ |
|
|
309 |
delay = static_cast<uint64_t> (m_jitter->GetValue (0, MAX_RA_DELAY_TIME) + 0.5); |
| 310 |
t = Simulator::Now () + MilliSeconds (delay); /* absolute time of solicited RA */ |
| 278 |
|
311 |
|
| 279 |
/* if our solicited RA is before the next periodic RA, we schedule it */ |
312 |
/* 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 ())) |
313 |
bool scheduleSingle = true; |
| 281 |
{ |
314 |
if ( m_eventIds.find ((*it)->GetInterface ()) != m_eventIds.end ()) |
| 282 |
NS_LOG_INFO ("schedule new RA"); |
315 |
{ |
| 283 |
EventId ei; |
316 |
if (t.GetTimeStep () > static_cast<int64_t> (m_eventIds[(*it)->GetInterface ()].GetTs ())) |
| 284 |
|
317 |
{ |
| 285 |
ScheduleTransmit (MilliSeconds (delay), (*it), ei, address.GetIpv6 (), false); |
318 |
scheduleSingle = false; |
|
|
319 |
} |
| 320 |
} |
| 321 |
if (scheduleSingle) |
| 322 |
{ |
| 323 |
NS_LOG_INFO ("schedule new RA"); |
| 324 |
Simulator::Schedule (MilliSeconds (delay), &Radvd::Send, this, (*it), address.GetIpv6 (), false); |
| 325 |
} |
| 286 |
} |
326 |
} |
| 287 |
} |
327 |
} |
| 288 |
break; |
328 |
break; |