PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/internet/model/ipv6-extension.cc

https://github.com/scarletttu/ns-3-codel-dev
C++ | 1056 lines | 802 code | 217 blank | 37 comment | 111 complexity | f6a352eac5faf9a931e046b1067d036a MD5 | raw file
Possible License(s): GPL-2.0
  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: David Gross <gdavid.devel@gmail.com>
  19. */
  20. #include <list>
  21. #include <ctime>
  22. #include "ns3/log.h"
  23. #include "ns3/assert.h"
  24. #include "ns3/uinteger.h"
  25. #include "ns3/object-vector.h"
  26. #include "ns3/ipv6-address.h"
  27. #include "ns3/ipv6-header.h"
  28. #include "ns3/ipv6-l3-protocol.h"
  29. #include "ns3/ipv6-static-routing.h"
  30. #include "ns3/ipv6-list-routing.h"
  31. #include "ns3/ipv6-route.h"
  32. #include "ns3/trace-source-accessor.h"
  33. #include "ns3/random-variable.h"
  34. #include "icmpv6-l4-protocol.h"
  35. #include "ipv6-extension-demux.h"
  36. #include "ipv6-extension.h"
  37. #include "ipv6-extension-header.h"
  38. #include "ipv6-option-demux.h"
  39. #include "ipv6-option.h"
  40. #include "udp-header.h"
  41. NS_LOG_COMPONENT_DEFINE ("Ipv6Extension");
  42. namespace ns3 {
  43. NS_OBJECT_ENSURE_REGISTERED (Ipv6Extension);
  44. TypeId Ipv6Extension::GetTypeId ()
  45. {
  46. static TypeId tid = TypeId ("ns3::Ipv6Extension")
  47. .SetParent<Object> ()
  48. .AddAttribute ("ExtensionNumber", "The IPv6 extension number.",
  49. UintegerValue (0),
  50. MakeUintegerAccessor (&Ipv6Extension::GetExtensionNumber),
  51. MakeUintegerChecker<uint8_t> ())
  52. .AddTraceSource ("Drop", "Drop ipv6 packet",
  53. MakeTraceSourceAccessor (&Ipv6Extension::m_dropTrace))
  54. ;
  55. return tid;
  56. }
  57. Ipv6Extension::~Ipv6Extension ()
  58. {
  59. NS_LOG_FUNCTION_NOARGS ();
  60. }
  61. void Ipv6Extension::SetNode (Ptr<Node> node)
  62. {
  63. NS_LOG_FUNCTION (this << node);
  64. m_node = node;
  65. }
  66. Ptr<Node> Ipv6Extension::GetNode () const
  67. {
  68. NS_LOG_FUNCTION_NOARGS ();
  69. return m_node;
  70. }
  71. uint8_t Ipv6Extension::ProcessOptions (Ptr<Packet>& packet, uint8_t offset, uint8_t length, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  72. {
  73. NS_LOG_FUNCTION (this << packet << offset << length << ipv6Header << dst << nextHeader << isDropped);
  74. // For ICMPv6 Error packets
  75. Ptr<Packet> malformedPacket = packet->Copy ();
  76. malformedPacket->AddHeader (ipv6Header);
  77. Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
  78. Ptr<Packet> p = packet->Copy ();
  79. p->RemoveAtStart (offset);
  80. Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode ()->GetObject<Ipv6OptionDemux> ();
  81. Ptr<Ipv6Option> ipv6Option;
  82. uint8_t processedSize = 0;
  83. uint32_t size = p->GetSize ();
  84. uint8_t *data = new uint8_t[size];
  85. p->CopyData (data, size);
  86. uint8_t optionType = 0;
  87. uint8_t optionLength = 0;
  88. while (length > processedSize && !isDropped)
  89. {
  90. optionType = *(data + processedSize);
  91. ipv6Option = ipv6OptionDemux->GetOption (optionType);
  92. if (ipv6Option == 0)
  93. {
  94. optionType >>= 6;
  95. switch (optionType)
  96. {
  97. case 0:
  98. optionLength = *(data + processedSize + 1) + 2;
  99. break;
  100. case 1:
  101. NS_LOG_LOGIC ("Unknown Option. Drop!");
  102. m_dropTrace (packet);
  103. optionLength = 0;
  104. isDropped = true;
  105. break;
  106. case 2:
  107. NS_LOG_LOGIC ("Unknown Option. Drop!");
  108. icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
  109. m_dropTrace (packet);
  110. optionLength = 0;
  111. isDropped = true;
  112. break;
  113. case 3:
  114. NS_LOG_LOGIC ("Unknown Option. Drop!");
  115. if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
  116. {
  117. icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize);
  118. m_dropTrace (packet);
  119. optionLength = 0;
  120. isDropped = true;
  121. break;
  122. }
  123. m_dropTrace (packet);
  124. optionLength = 0;
  125. isDropped = true;
  126. break;
  127. default:
  128. break;
  129. }
  130. }
  131. else
  132. {
  133. optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, isDropped);
  134. }
  135. processedSize += optionLength;
  136. p->RemoveAtStart (optionLength);
  137. }
  138. delete [] data;
  139. return processedSize;
  140. }
  141. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHopByHop);
  142. TypeId Ipv6ExtensionHopByHop::GetTypeId ()
  143. {
  144. static TypeId tid = TypeId ("ns3::Ipv6ExtensionHopByHop")
  145. .SetParent<Ipv6Extension> ()
  146. .AddConstructor<Ipv6ExtensionHopByHop> ()
  147. ;
  148. return tid;
  149. }
  150. Ipv6ExtensionHopByHop::Ipv6ExtensionHopByHop ()
  151. {
  152. NS_LOG_FUNCTION_NOARGS ();
  153. }
  154. Ipv6ExtensionHopByHop::~Ipv6ExtensionHopByHop ()
  155. {
  156. NS_LOG_FUNCTION_NOARGS ();
  157. }
  158. uint8_t Ipv6ExtensionHopByHop::GetExtensionNumber () const
  159. {
  160. NS_LOG_FUNCTION_NOARGS ();
  161. return EXT_NUMBER;
  162. }
  163. uint8_t Ipv6ExtensionHopByHop::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  164. {
  165. NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
  166. Ptr<Packet> p = packet->Copy ();
  167. p->RemoveAtStart (offset);
  168. Ipv6ExtensionHopByHopHeader hopbyhopHeader;
  169. p->RemoveHeader (hopbyhopHeader);
  170. if (nextHeader)
  171. {
  172. *nextHeader = hopbyhopHeader.GetNextHeader ();
  173. }
  174. uint8_t processedSize = hopbyhopHeader.GetOptionsOffset ();
  175. offset += processedSize;
  176. uint8_t length = hopbyhopHeader.GetLength () - hopbyhopHeader.GetOptionsOffset ();
  177. processedSize += ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
  178. return processedSize;
  179. }
  180. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionDestination);
  181. TypeId Ipv6ExtensionDestination::GetTypeId ()
  182. {
  183. static TypeId tid = TypeId ("ns3::Ipv6ExtensionDestination")
  184. .SetParent<Ipv6Extension> ()
  185. .AddConstructor<Ipv6ExtensionDestination> ()
  186. ;
  187. return tid;
  188. }
  189. Ipv6ExtensionDestination::Ipv6ExtensionDestination ()
  190. {
  191. NS_LOG_FUNCTION_NOARGS ();
  192. }
  193. Ipv6ExtensionDestination::~Ipv6ExtensionDestination ()
  194. {
  195. NS_LOG_FUNCTION_NOARGS ();
  196. }
  197. uint8_t Ipv6ExtensionDestination::GetExtensionNumber () const
  198. {
  199. NS_LOG_FUNCTION_NOARGS ();
  200. return EXT_NUMBER;
  201. }
  202. uint8_t Ipv6ExtensionDestination::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  203. {
  204. NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
  205. Ptr<Packet> p = packet->Copy ();
  206. p->RemoveAtStart (offset);
  207. Ipv6ExtensionDestinationHeader destinationHeader;
  208. p->RemoveHeader (destinationHeader);
  209. if (nextHeader)
  210. {
  211. *nextHeader = destinationHeader.GetNextHeader ();
  212. }
  213. uint8_t processedSize = destinationHeader.GetOptionsOffset ();
  214. offset += processedSize;
  215. uint8_t length = destinationHeader.GetLength () - destinationHeader.GetOptionsOffset ();
  216. processedSize += ProcessOptions (packet, offset, length, ipv6Header, dst, nextHeader, isDropped);
  217. return processedSize;
  218. }
  219. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionFragment);
  220. TypeId Ipv6ExtensionFragment::GetTypeId ()
  221. {
  222. static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragment")
  223. .SetParent<Ipv6Extension> ()
  224. .AddConstructor<Ipv6ExtensionFragment> ()
  225. ;
  226. return tid;
  227. }
  228. Ipv6ExtensionFragment::Ipv6ExtensionFragment ()
  229. {
  230. NS_LOG_FUNCTION_NOARGS ();
  231. }
  232. Ipv6ExtensionFragment::~Ipv6ExtensionFragment ()
  233. {
  234. NS_LOG_FUNCTION_NOARGS ();
  235. }
  236. void Ipv6ExtensionFragment::DoDispose ()
  237. {
  238. NS_LOG_FUNCTION_NOARGS ();
  239. for (MapFragments_t::iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
  240. {
  241. it->second = 0;
  242. }
  243. m_fragments.clear ();
  244. Ipv6Extension::DoDispose ();
  245. }
  246. uint8_t Ipv6ExtensionFragment::GetExtensionNumber () const
  247. {
  248. NS_LOG_FUNCTION_NOARGS ();
  249. return EXT_NUMBER;
  250. }
  251. uint8_t Ipv6ExtensionFragment::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  252. {
  253. NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
  254. Ptr<Packet> p = packet->Copy ();
  255. p->RemoveAtStart (offset);
  256. Ipv6ExtensionFragmentHeader fragmentHeader;
  257. p->RemoveHeader (fragmentHeader);
  258. if (nextHeader)
  259. {
  260. *nextHeader = fragmentHeader.GetNextHeader ();
  261. }
  262. bool moreFragment = fragmentHeader.GetMoreFragment ();
  263. uint16_t fragmentOffset = fragmentHeader.GetOffset ();
  264. uint32_t identification = fragmentHeader.GetIdentification ();
  265. Ipv6Address src = ipv6Header.GetSourceAddress ();
  266. std::pair<Ipv6Address, uint32_t> fragmentsId = std::make_pair<Ipv6Address, uint32_t> (src, identification);
  267. Ptr<Fragments> fragments;
  268. Ipv6Header ipHeader = ipv6Header;
  269. ipHeader.SetNextHeader (fragmentHeader.GetNextHeader ());
  270. MapFragments_t::iterator it = m_fragments.find (fragmentsId);
  271. if (it == m_fragments.end ())
  272. {
  273. fragments = Create<Fragments> ();
  274. m_fragments.insert (std::make_pair (fragmentsId, fragments));
  275. EventId timeout = Simulator::Schedule (Seconds (60),
  276. &Ipv6ExtensionFragment::HandleFragmentsTimeout, this,
  277. fragmentsId, fragments, ipHeader);
  278. fragments->SetTimeoutEventId (timeout);
  279. }
  280. else
  281. {
  282. fragments = it->second;
  283. }
  284. if (fragmentOffset == 0)
  285. {
  286. Ptr<Packet> unfragmentablePart = packet->Copy ();
  287. unfragmentablePart->RemoveAtEnd (packet->GetSize () - offset);
  288. fragments->SetUnfragmentablePart (unfragmentablePart);
  289. }
  290. fragments->AddFragment (p, fragmentOffset, moreFragment);
  291. if (fragments->IsEntire ())
  292. {
  293. packet = fragments->GetPacket ();
  294. fragments->CancelTimeout ();
  295. m_fragments.erase (fragmentsId);
  296. isDropped = false;
  297. }
  298. else
  299. {
  300. // the fragment is not "dropped", but Ipv6L3Protocol::LocalDeliver must stop processing it.
  301. isDropped = true;
  302. }
  303. return 0;
  304. }
  305. void Ipv6ExtensionFragment::GetFragments (Ptr<Packet> packet, uint32_t maxFragmentSize, std::list<Ptr<Packet> >& listFragments)
  306. {
  307. Ptr<Packet> p = packet->Copy ();
  308. Ipv6Header ipv6Header;
  309. p->RemoveHeader (ipv6Header);
  310. uint8_t nextHeader = ipv6Header.GetNextHeader ();
  311. uint8_t ipv6HeaderSize = ipv6Header.GetSerializedSize ();
  312. uint8_t type;
  313. p->CopyData (&type, sizeof(type));
  314. bool moreHeader = true;
  315. if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
  316. || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
  317. {
  318. moreHeader = false;
  319. ipv6Header.SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
  320. }
  321. std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
  322. uint32_t unfragmentablePartSize = 0;
  323. Ptr<Ipv6ExtensionDemux> extensionDemux = GetNode ()->GetObject<Ipv6ExtensionDemux> ();
  324. Ptr<Ipv6Extension> extension = extensionDemux->GetExtension (nextHeader);
  325. uint8_t extensionHeaderLength;
  326. while (moreHeader)
  327. {
  328. if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
  329. {
  330. Ipv6ExtensionHopByHopHeader *hopbyhopHeader = new Ipv6ExtensionHopByHopHeader ();
  331. p->RemoveHeader (*hopbyhopHeader);
  332. nextHeader = hopbyhopHeader->GetNextHeader ();
  333. extensionHeaderLength = hopbyhopHeader->GetLength ();
  334. uint8_t type;
  335. p->CopyData (&type, sizeof(type));
  336. if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
  337. || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
  338. {
  339. moreHeader = false;
  340. hopbyhopHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
  341. }
  342. unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP));
  343. unfragmentablePartSize += extensionHeaderLength;
  344. }
  345. else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
  346. {
  347. uint8_t buf[2];
  348. p->CopyData (buf, sizeof(buf));
  349. uint8_t numberAddress = buf[1] / 2;
  350. Ipv6ExtensionLooseRoutingHeader *routingHeader = new Ipv6ExtensionLooseRoutingHeader ();
  351. routingHeader->SetNumberAddress (numberAddress);
  352. p->RemoveHeader (*routingHeader);
  353. nextHeader = routingHeader->GetNextHeader ();
  354. extensionHeaderLength = routingHeader->GetLength ();
  355. uint8_t type;
  356. p->CopyData (&type, sizeof(type));
  357. if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
  358. || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
  359. {
  360. moreHeader = false;
  361. routingHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
  362. }
  363. unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (routingHeader, Ipv6Header::IPV6_EXT_ROUTING));
  364. unfragmentablePartSize += extensionHeaderLength;
  365. }
  366. else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
  367. {
  368. Ipv6ExtensionDestinationHeader *destinationHeader = new Ipv6ExtensionDestinationHeader ();
  369. p->RemoveHeader (*destinationHeader);
  370. nextHeader = destinationHeader->GetNextHeader ();
  371. extensionHeaderLength = destinationHeader->GetLength ();
  372. uint8_t type;
  373. p->CopyData (&type, sizeof(type));
  374. if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
  375. || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && type == Ipv6Header::IPV6_EXT_ROUTING)))
  376. {
  377. moreHeader = false;
  378. destinationHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
  379. }
  380. unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION));
  381. unfragmentablePartSize += extensionHeaderLength;
  382. }
  383. }
  384. Ipv6ExtensionFragmentHeader fragmentHeader;
  385. uint8_t fragmentHeaderSize = fragmentHeader.GetSerializedSize ();
  386. uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
  387. uint32_t currentFragmentablePartSize = 0;
  388. bool moreFragment = true;
  389. UniformVariable uvar;
  390. uint32_t identification = (uint32_t) uvar.GetValue (0, (uint32_t)-1);
  391. uint16_t offset = 0;
  392. do
  393. {
  394. if (p->GetSize () > offset + maxFragmentablePartSize)
  395. {
  396. moreFragment = true;
  397. currentFragmentablePartSize = maxFragmentablePartSize;
  398. }
  399. else
  400. {
  401. moreFragment = false;
  402. currentFragmentablePartSize = p->GetSize () - offset;
  403. }
  404. currentFragmentablePartSize -= currentFragmentablePartSize % 8;
  405. fragmentHeader.SetNextHeader (nextHeader);
  406. fragmentHeader.SetLength (currentFragmentablePartSize);
  407. fragmentHeader.SetOffset (offset);
  408. fragmentHeader.SetMoreFragment (moreFragment);
  409. fragmentHeader.SetIdentification (identification);
  410. Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
  411. offset += currentFragmentablePartSize;
  412. fragment->AddHeader (fragmentHeader);
  413. for (std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
  414. {
  415. if (it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
  416. {
  417. fragment->AddHeader (*dynamic_cast<Ipv6ExtensionHopByHopHeader *> (it->first));
  418. }
  419. else if (it->second == Ipv6Header::IPV6_EXT_ROUTING)
  420. {
  421. fragment->AddHeader (*dynamic_cast<Ipv6ExtensionLooseRoutingHeader *> (it->first));
  422. }
  423. else if (it->second == Ipv6Header::IPV6_EXT_DESTINATION)
  424. {
  425. fragment->AddHeader (*dynamic_cast<Ipv6ExtensionDestinationHeader *> (it->first));
  426. }
  427. }
  428. ipv6Header.SetPayloadLength (fragment->GetSize ());
  429. fragment->AddHeader (ipv6Header);
  430. std::ostringstream oss;
  431. fragment->Print (oss);
  432. listFragments.push_back (fragment);
  433. }
  434. while (moreFragment);
  435. for (std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
  436. {
  437. delete it->first;
  438. }
  439. unfragmentablePart.clear ();
  440. }
  441. void Ipv6ExtensionFragment::HandleFragmentsTimeout (std::pair<Ipv6Address, uint32_t> fragmentsId, Ptr<Fragments> fragments, Ipv6Header & ipHeader)
  442. {
  443. Ptr<Packet> packet = fragments->GetPartialPacket ();
  444. packet->AddHeader (ipHeader);
  445. // if we have at least 8 bytes, we can send an ICMP.
  446. if ( packet->GetSize () > 8 )
  447. {
  448. Ptr<Icmpv6L4Protocol> icmp = GetNode ()->GetObject<Icmpv6L4Protocol> ();
  449. icmp->SendErrorTimeExceeded (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_FRAGTIME);
  450. }
  451. m_dropTrace (packet);
  452. // clear the buffers
  453. m_fragments.erase (fragmentsId);
  454. }
  455. Ipv6ExtensionFragment::Fragments::Fragments ()
  456. : m_moreFragment (0)
  457. {
  458. }
  459. Ipv6ExtensionFragment::Fragments::~Fragments ()
  460. {
  461. }
  462. void Ipv6ExtensionFragment::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment)
  463. {
  464. std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
  465. for (it = m_fragments.begin (); it != m_fragments.end (); it++)
  466. {
  467. if (it->second > fragmentOffset)
  468. {
  469. break;
  470. }
  471. }
  472. if (it == m_fragments.end ())
  473. {
  474. m_moreFragment = moreFragment;
  475. }
  476. m_fragments.insert (it, std::make_pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
  477. }
  478. void Ipv6ExtensionFragment::Fragments::SetUnfragmentablePart (Ptr<Packet> unfragmentablePart)
  479. {
  480. m_unfragmentable = unfragmentablePart;
  481. }
  482. bool Ipv6ExtensionFragment::Fragments::IsEntire () const
  483. {
  484. bool ret = !m_moreFragment && m_fragments.size () > 0;
  485. if (ret)
  486. {
  487. uint16_t lastEndOffset = 0;
  488. for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
  489. {
  490. if (lastEndOffset != it->second)
  491. {
  492. ret = false;
  493. break;
  494. }
  495. lastEndOffset += it->first->GetSize ();
  496. }
  497. }
  498. return ret;
  499. }
  500. Ptr<Packet> Ipv6ExtensionFragment::Fragments::GetPacket () const
  501. {
  502. Ptr<Packet> p = m_unfragmentable->Copy ();
  503. for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
  504. {
  505. p->AddAtEnd (it->first);
  506. }
  507. return p;
  508. }
  509. Ptr<Packet> Ipv6ExtensionFragment::Fragments::GetPartialPacket () const
  510. {
  511. Ptr<Packet> p;
  512. if ( m_unfragmentable )
  513. {
  514. p = m_unfragmentable->Copy ();
  515. }
  516. else
  517. {
  518. return p;
  519. }
  520. uint16_t lastEndOffset = 0;
  521. for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
  522. {
  523. if (lastEndOffset != it->second)
  524. {
  525. break;
  526. }
  527. p->AddAtEnd (it->first);
  528. lastEndOffset += it->first->GetSize ();
  529. }
  530. return p;
  531. }
  532. void Ipv6ExtensionFragment::Fragments::SetTimeoutEventId (EventId event)
  533. {
  534. m_timeoutEventId = event;
  535. return;
  536. }
  537. void Ipv6ExtensionFragment::Fragments::CancelTimeout ()
  538. {
  539. m_timeoutEventId.Cancel ();
  540. return;
  541. }
  542. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionRouting);
  543. TypeId Ipv6ExtensionRouting::GetTypeId ()
  544. {
  545. static TypeId tid = TypeId ("ns3::Ipv6ExtensionRouting")
  546. .SetParent<Ipv6Extension> ()
  547. .AddConstructor<Ipv6ExtensionRouting> ()
  548. ;
  549. return tid;
  550. }
  551. Ipv6ExtensionRouting::Ipv6ExtensionRouting ()
  552. {
  553. NS_LOG_FUNCTION_NOARGS ();
  554. }
  555. Ipv6ExtensionRouting::~Ipv6ExtensionRouting ()
  556. {
  557. NS_LOG_FUNCTION_NOARGS ();
  558. }
  559. uint8_t Ipv6ExtensionRouting::GetExtensionNumber () const
  560. {
  561. NS_LOG_FUNCTION_NOARGS ();
  562. return EXT_NUMBER;
  563. }
  564. uint8_t Ipv6ExtensionRouting::GetTypeRouting () const
  565. {
  566. NS_LOG_FUNCTION_NOARGS ();
  567. return 0;
  568. }
  569. uint8_t Ipv6ExtensionRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  570. {
  571. NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
  572. // For ICMPv6 Error Packets
  573. Ptr<Packet> malformedPacket = packet->Copy ();
  574. malformedPacket->AddHeader (ipv6Header);
  575. Ptr<Packet> p = packet->Copy ();
  576. p->RemoveAtStart (offset);
  577. uint8_t buf[4];
  578. packet->CopyData (buf, sizeof(buf));
  579. uint8_t routingNextHeader = buf[0];
  580. uint8_t routingLength = buf[1];
  581. uint8_t routingTypeRouting = buf[2];
  582. uint8_t routingSegmentsLeft = buf[3];
  583. if (nextHeader)
  584. {
  585. *nextHeader = routingNextHeader;
  586. }
  587. Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
  588. Ptr<Ipv6ExtensionRoutingDemux> ipv6ExtensionRoutingDemux = GetNode ()->GetObject<Ipv6ExtensionRoutingDemux> ();
  589. Ptr<Ipv6ExtensionRouting> ipv6ExtensionRouting = ipv6ExtensionRoutingDemux->GetExtensionRouting (routingTypeRouting);
  590. if (ipv6ExtensionRouting == 0)
  591. {
  592. if (routingSegmentsLeft == 0)
  593. {
  594. isDropped = false;
  595. }
  596. else
  597. {
  598. NS_LOG_LOGIC ("Malformed header. Drop!");
  599. icmpv6->SendErrorParameterError (malformedPacket, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
  600. m_dropTrace (packet);
  601. isDropped = true;
  602. }
  603. return routingLength;
  604. }
  605. return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (uint8_t *)0, isDropped);
  606. }
  607. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionRoutingDemux);
  608. TypeId Ipv6ExtensionRoutingDemux::GetTypeId ()
  609. {
  610. static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingDemux")
  611. .SetParent<Object> ()
  612. .AddAttribute ("Routing Extensions", "The set of IPv6 Routing extensions registered with this demux.",
  613. ObjectVectorValue (),
  614. MakeObjectVectorAccessor (&Ipv6ExtensionRoutingDemux::m_extensionsRouting),
  615. MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
  616. ;
  617. return tid;
  618. }
  619. Ipv6ExtensionRoutingDemux::Ipv6ExtensionRoutingDemux ()
  620. {
  621. }
  622. Ipv6ExtensionRoutingDemux::~Ipv6ExtensionRoutingDemux ()
  623. {
  624. }
  625. void Ipv6ExtensionRoutingDemux::DoDispose ()
  626. {
  627. for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
  628. {
  629. (*it)->Dispose ();
  630. *it = 0;
  631. }
  632. m_extensionsRouting.clear ();
  633. m_node = 0;
  634. Object::DoDispose ();
  635. }
  636. void Ipv6ExtensionRoutingDemux::SetNode (Ptr<Node> node)
  637. {
  638. m_node = node;
  639. }
  640. void Ipv6ExtensionRoutingDemux::Insert (Ptr<Ipv6ExtensionRouting> extensionRouting)
  641. {
  642. m_extensionsRouting.push_back (extensionRouting);
  643. }
  644. Ptr<Ipv6ExtensionRouting> Ipv6ExtensionRoutingDemux::GetExtensionRouting (uint8_t typeRouting)
  645. {
  646. for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
  647. {
  648. if ((*i)->GetTypeRouting () == typeRouting)
  649. {
  650. return *i;
  651. }
  652. }
  653. return 0;
  654. }
  655. void Ipv6ExtensionRoutingDemux::Remove (Ptr<Ipv6ExtensionRouting> extensionRouting)
  656. {
  657. m_extensionsRouting.remove (extensionRouting);
  658. }
  659. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionLooseRouting);
  660. TypeId Ipv6ExtensionLooseRouting::GetTypeId ()
  661. {
  662. static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRouting")
  663. .SetParent<Ipv6ExtensionRouting> ()
  664. .AddConstructor<Ipv6ExtensionLooseRouting> ()
  665. ;
  666. return tid;
  667. }
  668. Ipv6ExtensionLooseRouting::Ipv6ExtensionLooseRouting ()
  669. {
  670. NS_LOG_FUNCTION_NOARGS ();
  671. }
  672. Ipv6ExtensionLooseRouting::~Ipv6ExtensionLooseRouting ()
  673. {
  674. NS_LOG_FUNCTION_NOARGS ();
  675. }
  676. uint8_t Ipv6ExtensionLooseRouting::GetTypeRouting () const
  677. {
  678. NS_LOG_FUNCTION_NOARGS ();
  679. return TYPE_ROUTING;
  680. }
  681. uint8_t Ipv6ExtensionLooseRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  682. {
  683. NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
  684. // For ICMPv6 Error packets
  685. Ptr<Packet> malformedPacket = packet->Copy ();
  686. malformedPacket->AddHeader (ipv6Header);
  687. Ptr<Packet> p = packet->Copy ();
  688. p->RemoveAtStart (offset);
  689. // Copy IPv6 Header : ipv6Header -> ipv6header
  690. Buffer tmp;
  691. tmp.AddAtStart (ipv6Header.GetSerializedSize ());
  692. Buffer::Iterator it = tmp.Begin ();
  693. Ipv6Header ipv6header;
  694. ipv6Header.Serialize (it);
  695. ipv6header.Deserialize (it);
  696. // Get the number of routers' address field
  697. uint8_t buf[2];
  698. p->CopyData (buf, sizeof(buf));
  699. uint8_t numberAddress = buf[1] / 2;
  700. Ipv6ExtensionLooseRoutingHeader routingHeader;
  701. routingHeader.SetNumberAddress (numberAddress);
  702. p->RemoveHeader (routingHeader);
  703. if (nextHeader)
  704. {
  705. *nextHeader = routingHeader.GetNextHeader ();
  706. }
  707. Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
  708. Ipv6Address srcAddress = ipv6header.GetSourceAddress ();
  709. Ipv6Address destAddress = ipv6header.GetDestinationAddress ();
  710. uint8_t hopLimit = ipv6header.GetHopLimit ();
  711. uint8_t segmentsLeft = routingHeader.GetSegmentsLeft ();
  712. uint8_t length = (routingHeader.GetLength () >> 3) - 1;
  713. uint8_t nbAddress = length / 2;
  714. uint8_t nextAddressIndex;
  715. Ipv6Address nextAddress;
  716. if (segmentsLeft == 0)
  717. {
  718. isDropped = false;
  719. return routingHeader.GetSerializedSize ();
  720. }
  721. if (length % 2 != 0)
  722. {
  723. NS_LOG_LOGIC ("Malformed header. Drop!");
  724. icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1);
  725. m_dropTrace (packet);
  726. isDropped = true;
  727. return routingHeader.GetSerializedSize ();
  728. }
  729. if (segmentsLeft > nbAddress)
  730. {
  731. NS_LOG_LOGIC ("Malformed header. Drop!");
  732. icmpv6->SendErrorParameterError (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 3);
  733. m_dropTrace (packet);
  734. isDropped = true;
  735. return routingHeader.GetSerializedSize ();
  736. }
  737. routingHeader.SetSegmentsLeft (segmentsLeft - 1);
  738. nextAddressIndex = nbAddress - segmentsLeft;
  739. nextAddress = routingHeader.GetRouterAddress (nextAddressIndex);
  740. if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
  741. {
  742. m_dropTrace (packet);
  743. isDropped = true;
  744. return routingHeader.GetSerializedSize ();
  745. }
  746. routingHeader.SetRouterAddress (nextAddressIndex, destAddress);
  747. ipv6header.SetDestinationAddress (nextAddress);
  748. if (hopLimit <= 1)
  749. {
  750. NS_LOG_LOGIC ("Time Exceeded : Hop Limit <= 1. Drop!");
  751. icmpv6->SendErrorTimeExceeded (malformedPacket, srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT);
  752. m_dropTrace (packet);
  753. isDropped = true;
  754. return routingHeader.GetSerializedSize ();
  755. }
  756. routingHeader.SetLength (88);
  757. ipv6header.SetHopLimit (hopLimit - 1);
  758. p->AddHeader (routingHeader);
  759. /* short-circuiting routing stuff
  760. *
  761. * If we process this option,
  762. * the packet was for us so we resend it to
  763. * the new destination (modified in the header above).
  764. */
  765. Ptr<Ipv6L3Protocol> ipv6 = GetNode ()->GetObject<Ipv6L3Protocol> ();
  766. Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
  767. Socket::SocketErrno err;
  768. NS_ASSERT (ipv6rp);
  769. Ptr<Ipv6Route> rtentry = ipv6rp->RouteOutput (p, ipv6header, 0, err);
  770. if (rtentry)
  771. {
  772. /* we know a route exists so send packet now */
  773. ipv6->SendRealOut (rtentry, p, ipv6header);
  774. }
  775. else
  776. {
  777. NS_LOG_INFO ("No route for next router");
  778. }
  779. /* as we directly send packet, mark it as dropped */
  780. isDropped = true;
  781. return routingHeader.GetSerializedSize ();
  782. }
  783. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionESP);
  784. TypeId Ipv6ExtensionESP::GetTypeId ()
  785. {
  786. static TypeId tid = TypeId ("ns3::Ipv6ExtensionESP")
  787. .SetParent<Ipv6Extension> ()
  788. .AddConstructor<Ipv6ExtensionESP> ()
  789. ;
  790. return tid;
  791. }
  792. Ipv6ExtensionESP::Ipv6ExtensionESP ()
  793. {
  794. NS_LOG_FUNCTION_NOARGS ();
  795. }
  796. Ipv6ExtensionESP::~Ipv6ExtensionESP ()
  797. {
  798. NS_LOG_FUNCTION_NOARGS ();
  799. }
  800. uint8_t Ipv6ExtensionESP::GetExtensionNumber () const
  801. {
  802. NS_LOG_FUNCTION_NOARGS ();
  803. return EXT_NUMBER;
  804. }
  805. uint8_t Ipv6ExtensionESP::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  806. {
  807. NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
  808. /* TODO */
  809. return 0;
  810. }
  811. NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionAH);
  812. TypeId Ipv6ExtensionAH::GetTypeId ()
  813. {
  814. static TypeId tid = TypeId ("ns3::Ipv6ExtensionAH")
  815. .SetParent<Ipv6Extension> ()
  816. .AddConstructor<Ipv6ExtensionAH> ()
  817. ;
  818. return tid;
  819. }
  820. Ipv6ExtensionAH::Ipv6ExtensionAH ()
  821. {
  822. NS_LOG_FUNCTION_NOARGS ();
  823. }
  824. Ipv6ExtensionAH::~Ipv6ExtensionAH ()
  825. {
  826. NS_LOG_FUNCTION_NOARGS ();
  827. }
  828. uint8_t Ipv6ExtensionAH::GetExtensionNumber () const
  829. {
  830. NS_LOG_FUNCTION_NOARGS ();
  831. return EXT_NUMBER;
  832. }
  833. uint8_t Ipv6ExtensionAH::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
  834. {
  835. NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
  836. /* TODO */
  837. return true;
  838. }
  839. } /* namespace ns3 */