PageRenderTime 27ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/ns-3.19/src/internet/model/ipv6-interface.cc

https://bitbucket.org/DiiManut/ns19-vanet-routing
C++ | 500 lines | 394 code | 73 blank | 33 comment | 60 complexity | 20992198e7f3255e67a55b56cb77c776 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  2. /*
  3. * Copyright (c) 2007-2009 Strasbourg University
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation;
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
  19. */
  20. #include "ns3/log.h"
  21. #include "ns3/node.h"
  22. #include "ns3/packet.h"
  23. #include "ipv6-interface.h"
  24. #include "ns3/net-device.h"
  25. #include "loopback-net-device.h"
  26. #include "ns3/mac16-address.h"
  27. #include "ns3/mac64-address.h"
  28. #include "ipv6-l3-protocol.h"
  29. #include "icmpv6-l4-protocol.h"
  30. #include "ndisc-cache.h"
  31. namespace ns3
  32. {
  33. NS_LOG_COMPONENT_DEFINE ("Ipv6Interface")
  34. ;
  35. NS_OBJECT_ENSURE_REGISTERED (Ipv6Interface)
  36. ;
  37. TypeId Ipv6Interface::GetTypeId ()
  38. {
  39. static TypeId tid = TypeId ("ns3::Ipv6Interface")
  40. .SetParent<Object> ()
  41. ;
  42. return tid;
  43. }
  44. Ipv6Interface::Ipv6Interface ()
  45. : m_ifup (false),
  46. m_forwarding (true),
  47. m_metric (1),
  48. m_node (0),
  49. m_device (0),
  50. m_ndCache (0),
  51. m_curHopLimit (0),
  52. m_baseReachableTime (0),
  53. m_reachableTime (0),
  54. m_retransTimer (0)
  55. {
  56. NS_LOG_FUNCTION (this);
  57. }
  58. Ipv6Interface::~Ipv6Interface ()
  59. {
  60. NS_LOG_FUNCTION_NOARGS ();
  61. }
  62. void Ipv6Interface::DoDispose ()
  63. {
  64. NS_LOG_FUNCTION_NOARGS ();
  65. m_node = 0;
  66. m_device = 0;
  67. m_ndCache = 0;
  68. Object::DoDispose ();
  69. }
  70. void Ipv6Interface::DoSetup ()
  71. {
  72. NS_LOG_FUNCTION_NOARGS ();
  73. if (m_node == 0 || m_device == 0)
  74. {
  75. return;
  76. }
  77. /* set up link-local address */
  78. if (!DynamicCast<LoopbackNetDevice> (m_device)) /* no autoconf for ip6-localhost */
  79. {
  80. Address addr = GetDevice ()->GetAddress ();
  81. if (Mac64Address::IsMatchingType (addr))
  82. {
  83. Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac64Address::ConvertFrom (addr)), Ipv6Prefix (64));
  84. AddAddress (ifaddr);
  85. }
  86. else if (Mac48Address::IsMatchingType (addr))
  87. {
  88. Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address::ConvertFrom (addr)), Ipv6Prefix (64));
  89. AddAddress (ifaddr);
  90. }
  91. else if (Mac16Address::IsMatchingType (addr))
  92. {
  93. Ipv6InterfaceAddress ifaddr = Ipv6InterfaceAddress (Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac16Address::ConvertFrom (addr)), Ipv6Prefix (64));
  94. AddAddress (ifaddr);
  95. }
  96. else
  97. {
  98. NS_ASSERT_MSG (false, "IPv6 autoconf for this kind of address not implemented.");
  99. }
  100. }
  101. else
  102. {
  103. return; /* no NDISC cache for ip6-localhost */
  104. }
  105. Ptr<Icmpv6L4Protocol> icmpv6 = m_node->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
  106. if (m_device->NeedsArp ())
  107. {
  108. m_ndCache = icmpv6->CreateCache (m_device, this);
  109. }
  110. }
  111. void Ipv6Interface::SetNode (Ptr<Node> node)
  112. {
  113. NS_LOG_FUNCTION (this << node);
  114. m_node = node;
  115. DoSetup ();
  116. }
  117. void Ipv6Interface::SetDevice (Ptr<NetDevice> device)
  118. {
  119. NS_LOG_FUNCTION (this << device);
  120. m_device = device;
  121. DoSetup ();
  122. }
  123. Ptr<NetDevice> Ipv6Interface::GetDevice () const
  124. {
  125. NS_LOG_FUNCTION_NOARGS ();
  126. return m_device;
  127. }
  128. void Ipv6Interface::SetMetric (uint16_t metric)
  129. {
  130. NS_LOG_FUNCTION (this << metric);
  131. m_metric = metric;
  132. }
  133. uint16_t Ipv6Interface::GetMetric () const
  134. {
  135. NS_LOG_FUNCTION_NOARGS ();
  136. return m_metric;
  137. }
  138. bool Ipv6Interface::IsUp () const
  139. {
  140. NS_LOG_FUNCTION_NOARGS ();
  141. return m_ifup;
  142. }
  143. bool Ipv6Interface::IsDown () const
  144. {
  145. NS_LOG_FUNCTION_NOARGS ();
  146. return !m_ifup;
  147. }
  148. void Ipv6Interface::SetUp ()
  149. {
  150. NS_LOG_FUNCTION_NOARGS ();
  151. if (m_ifup)
  152. {
  153. return;
  154. }
  155. m_ifup = true;
  156. }
  157. void Ipv6Interface::SetDown ()
  158. {
  159. NS_LOG_FUNCTION_NOARGS ();
  160. m_ifup = false;
  161. m_addresses.clear ();
  162. }
  163. bool Ipv6Interface::IsForwarding () const
  164. {
  165. NS_LOG_FUNCTION_NOARGS ();
  166. return m_forwarding;
  167. }
  168. void Ipv6Interface::SetForwarding (bool forwarding)
  169. {
  170. NS_LOG_FUNCTION (this << forwarding);
  171. m_forwarding = forwarding;
  172. }
  173. bool Ipv6Interface::AddAddress (Ipv6InterfaceAddress iface)
  174. {
  175. NS_LOG_FUNCTION_NOARGS ();
  176. Ipv6Address addr = iface.GetAddress ();
  177. /* DAD handling */
  178. if (!addr.IsAny ())
  179. {
  180. for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  181. {
  182. if ((*it).GetAddress () == addr)
  183. {
  184. return false;
  185. }
  186. }
  187. m_addresses.push_back (iface);
  188. if (!addr.IsAny () || !addr.IsLocalhost ())
  189. {
  190. /* DAD handling */
  191. Ptr<Icmpv6L4Protocol> icmpv6 = m_node->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
  192. if (icmpv6 && icmpv6->IsAlwaysDad ())
  193. {
  194. Simulator::Schedule (Seconds (0.), &Icmpv6L4Protocol::DoDAD, icmpv6, addr, this);
  195. Simulator::Schedule (Seconds (1.), &Icmpv6L4Protocol::FunctionDadTimeout, icmpv6, this, addr);
  196. }
  197. }
  198. return true;
  199. }
  200. /* bad address */
  201. return false;
  202. }
  203. Ipv6InterfaceAddress Ipv6Interface::GetLinkLocalAddress () const
  204. {
  205. /* IPv6 interface has always at least one IPv6 link-local address */
  206. NS_LOG_FUNCTION_NOARGS ();
  207. for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  208. {
  209. if ((*it).GetAddress ().IsLinkLocal ())
  210. {
  211. return (*it);
  212. }
  213. }
  214. NS_ASSERT_MSG (false, "No link-local address on interface " << this);
  215. Ipv6InterfaceAddress addr;
  216. return addr; /* quiet compiler */
  217. }
  218. Ipv6InterfaceAddress Ipv6Interface::GetAddress (uint32_t index) const
  219. {
  220. NS_LOG_FUNCTION (this << index);
  221. uint32_t i = 0;
  222. if (m_addresses.size () > index)
  223. {
  224. for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  225. {
  226. if (i == index)
  227. {
  228. return (*it);
  229. }
  230. i++;
  231. }
  232. }
  233. NS_ASSERT_MSG (false, "Address " << index << " not found");
  234. Ipv6InterfaceAddress addr;
  235. return addr; /* quiet compiler */
  236. }
  237. uint32_t Ipv6Interface::GetNAddresses () const
  238. {
  239. NS_LOG_FUNCTION_NOARGS ();
  240. return m_addresses.size ();
  241. }
  242. Ipv6InterfaceAddress Ipv6Interface::RemoveAddress (uint32_t index)
  243. {
  244. NS_LOG_FUNCTION (this << index);
  245. uint32_t i = 0;
  246. if (m_addresses.size () < index)
  247. {
  248. NS_ASSERT_MSG (false, "Try to remove index that don't exist in Ipv6Interface::RemoveAddress");
  249. }
  250. for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  251. {
  252. if (i == index)
  253. {
  254. Ipv6InterfaceAddress iface = (*it);
  255. m_addresses.erase (it);
  256. return iface;
  257. }
  258. i++;
  259. }
  260. NS_ASSERT_MSG (false, "Address " << index << " not found");
  261. Ipv6InterfaceAddress addr;
  262. return addr; /* quiet compiler */
  263. }
  264. Ipv6InterfaceAddress
  265. Ipv6Interface::RemoveAddress(Ipv6Address address)
  266. {
  267. NS_LOG_FUNCTION(this << address);
  268. if (address == address.GetLoopback())
  269. {
  270. NS_LOG_WARN ("Cannot remove loopback address.");
  271. return Ipv6InterfaceAddress();
  272. }
  273. for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  274. {
  275. if((*it).GetAddress() == address)
  276. {
  277. Ipv6InterfaceAddress iface = (*it);
  278. m_addresses.erase(it);
  279. return iface;
  280. }
  281. }
  282. return Ipv6InterfaceAddress();
  283. }
  284. Ipv6InterfaceAddress Ipv6Interface::GetAddressMatchingDestination (Ipv6Address dst)
  285. {
  286. NS_LOG_FUNCTION (this << dst);
  287. for (Ipv6InterfaceAddressList::const_iterator it = m_addresses.begin (); it != m_addresses.end (); ++it)
  288. {
  289. Ipv6InterfaceAddress ifaddr = (*it);
  290. if (ifaddr.GetPrefix ().IsMatch (ifaddr.GetAddress (), dst))
  291. {
  292. return ifaddr;
  293. }
  294. }
  295. /* NS_ASSERT_MSG (false, "Not matching address."); */
  296. Ipv6InterfaceAddress ret;
  297. return ret; /* quiet compiler */
  298. }
  299. void Ipv6Interface::Send (Ptr<Packet> p, Ipv6Address dest)
  300. {
  301. NS_LOG_FUNCTION (this << p << dest);
  302. Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
  303. if (!IsUp ())
  304. {
  305. return;
  306. }
  307. /* check if destination is localhost (::1) */
  308. if (DynamicCast<LoopbackNetDevice> (m_device))
  309. {
  310. /** \todo additional checks needed here (such as whether multicast
  311. * goes to loopback)?
  312. */
  313. m_device->Send (p, m_device->GetBroadcast (), Ipv6L3Protocol::PROT_NUMBER);
  314. return;
  315. }
  316. /* check if destination is for one of our interface */
  317. for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  318. {
  319. if (dest == (*it).GetAddress ())
  320. {
  321. ipv6->Receive (m_device, p, Ipv6L3Protocol::PROT_NUMBER,
  322. m_device->GetBroadcast (),
  323. m_device->GetBroadcast (),
  324. NetDevice::PACKET_HOST // note: linux uses PACKET_LOOPBACK here
  325. );
  326. return;
  327. }
  328. }
  329. /* other address */
  330. if (m_device->NeedsArp ())
  331. {
  332. NS_LOG_LOGIC ("Needs ARP" << " " << dest);
  333. Ptr<Icmpv6L4Protocol> icmpv6 = ipv6->GetIcmpv6 ();
  334. Address hardwareDestination;
  335. bool found = false;
  336. NS_ASSERT (icmpv6);
  337. if (dest.IsMulticast ())
  338. {
  339. NS_LOG_LOGIC ("IsMulticast");
  340. NS_ASSERT_MSG (m_device->IsMulticast (), "Ipv6Interface::SendTo (): Sending multicast packet over non-multicast device");
  341. hardwareDestination = m_device->GetMulticast (dest);
  342. found = true;
  343. }
  344. else
  345. {
  346. NS_LOG_LOGIC ("NDISC Lookup");
  347. found = icmpv6->Lookup (p, dest, GetDevice (), m_ndCache, &hardwareDestination);
  348. }
  349. if (found)
  350. {
  351. NS_LOG_LOGIC ("Address Resolved. Send.");
  352. m_device->Send (p, hardwareDestination, Ipv6L3Protocol::PROT_NUMBER);
  353. }
  354. }
  355. else
  356. {
  357. NS_LOG_LOGIC ("Doesn't need ARP");
  358. m_device->Send (p, m_device->GetBroadcast (), Ipv6L3Protocol::PROT_NUMBER);
  359. }
  360. }
  361. void Ipv6Interface::SetCurHopLimit (uint8_t curHopLimit)
  362. {
  363. NS_LOG_FUNCTION (this << curHopLimit);
  364. m_curHopLimit = curHopLimit;
  365. }
  366. uint8_t Ipv6Interface::GetCurHopLimit () const
  367. {
  368. NS_LOG_FUNCTION_NOARGS ();
  369. return m_curHopLimit;
  370. }
  371. void Ipv6Interface::SetBaseReachableTime (uint16_t baseReachableTime)
  372. {
  373. NS_LOG_FUNCTION (this << baseReachableTime);
  374. m_baseReachableTime = baseReachableTime;
  375. }
  376. uint16_t Ipv6Interface::GetBaseReachableTime () const
  377. {
  378. NS_LOG_FUNCTION_NOARGS ();
  379. return m_baseReachableTime;
  380. }
  381. void Ipv6Interface::SetReachableTime (uint16_t reachableTime)
  382. {
  383. NS_LOG_FUNCTION (this << reachableTime);
  384. m_reachableTime = reachableTime;
  385. }
  386. uint16_t Ipv6Interface::GetReachableTime () const
  387. {
  388. NS_LOG_FUNCTION_NOARGS ();
  389. return m_reachableTime;
  390. }
  391. void Ipv6Interface::SetRetransTimer (uint16_t retransTimer)
  392. {
  393. NS_LOG_FUNCTION (this << retransTimer);
  394. m_retransTimer = retransTimer;
  395. }
  396. uint16_t Ipv6Interface::GetRetransTimer () const
  397. {
  398. NS_LOG_FUNCTION_NOARGS ();
  399. return m_retransTimer;
  400. }
  401. void Ipv6Interface::SetState (Ipv6Address address, Ipv6InterfaceAddress::State_e state)
  402. {
  403. NS_LOG_FUNCTION (this << address << state);
  404. for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  405. {
  406. if ((*it).GetAddress () == address)
  407. {
  408. (*it).SetState (state);
  409. return;
  410. }
  411. }
  412. /* not found, maybe address has expired */
  413. }
  414. void Ipv6Interface::SetNsDadUid (Ipv6Address address, uint32_t uid)
  415. {
  416. NS_LOG_FUNCTION (this << address << uid);
  417. for (Ipv6InterfaceAddressListI it = m_addresses.begin (); it != m_addresses.end (); ++it)
  418. {
  419. if ((*it).GetAddress () == address)
  420. {
  421. (*it).SetNsDadUid (uid);
  422. return;
  423. }
  424. }
  425. /* not found, maybe address has expired */
  426. }
  427. } /* namespace ns3 */