Add IPv6 extension files from old ns-3-ipv6 repository (not working yet).
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-extension-demux.cc Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#include <sstream>
+#include "ns3/node.h"
+#include "ns3/ptr.h"
+#include "ns3/object-vector.h"
+#include "ipv6-extension-demux.h"
+#include "ipv6-extension.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionDemux);
+
+TypeId Ipv6ExtensionDemux::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionDemux")
+ .SetParent<Object> ()
+ .AddAttribute ("Extensions", "The set of IPv6 extensions registered with this demux.",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&Ipv6ExtensionDemux::m_extensions),
+ MakeObjectVectorChecker<Ipv6Extension> ())
+ ;
+ return tid;
+}
+
+Ipv6ExtensionDemux::Ipv6ExtensionDemux ()
+{
+}
+
+Ipv6ExtensionDemux::~Ipv6ExtensionDemux ()
+{
+}
+
+void Ipv6ExtensionDemux::DoDispose ()
+{
+ for (Ipv6ExtensionList_t::iterator it = m_extensions.begin (); it != m_extensions.end (); it++)
+ {
+ (*it)->Dispose ();
+ *it = 0;
+ }
+ m_extensions.clear ();
+ m_node = 0;
+ Object::DoDispose ();
+}
+
+void Ipv6ExtensionDemux::SetNode (Ptr<Node> node)
+{
+ m_node = node;
+}
+
+void Ipv6ExtensionDemux::Insert (Ptr<Ipv6Extension> extension)
+{
+ m_extensions.push_back (extension);
+}
+
+Ptr<Ipv6Extension> Ipv6ExtensionDemux::GetExtension (uint8_t extensionNumber)
+{
+ for (Ipv6ExtensionList_t::iterator i = m_extensions.begin (); i != m_extensions.end (); ++i)
+ {
+ if ((*i)->GetExtensionNumber () == extensionNumber)
+ {
+ return *i;
+ }
+ }
+ return 0;
+}
+
+void Ipv6ExtensionDemux::Remove (Ptr<Ipv6Extension> extension)
+{
+ m_extensions.remove (extension);
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-extension-demux.h Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#ifndef IPV6_EXTENSION_DEMUX_H
+#define IPV6_EXTENSION_DEMUX_H
+
+#include <list>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
+namespace ns3
+{
+
+class Ipv6Extension;
+class Node;
+
+/**
+ * \class Ipv6ExtensionDemux
+ * \brief IPv6 Extension Demux.
+ */
+class Ipv6ExtensionDemux : public Object
+{
+ public:
+ /**
+ * \brief The interface ID.
+ * \return type ID
+ */
+ static TypeId GetTypeId (void);
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionDemux ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionDemux ();
+
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Insert a new IPv6 Extension.
+ * \param extension the extension to insert
+ */
+ void Insert (Ptr<Ipv6Extension> extension);
+
+ /**
+ * \brief Get the extension corresponding to extensionNumber.
+ * \param extensionNumber extension number of the extension to retrieve
+ * \return a matching IPv6 extension
+ */
+ Ptr<Ipv6Extension> GetExtension (uint8_t extensionNumber);
+
+ /**
+ * \brief Remove an extension from this demux.
+ * \param extension pointer on the extension to remove
+ */
+ void Remove (Ptr<Ipv6Extension> extension);
+
+ protected:
+ virtual void DoDispose();
+
+ private:
+ typedef std::list<Ptr<Ipv6Extension> > Ipv6ExtensionList_t;
+
+ /**
+ * \brief List of IPv6 Extensions supported.
+ */
+ Ipv6ExtensionList_t m_extensions;
+
+ /**
+ * \brief The node.
+ */
+ Ptr<Node> m_node;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_EXTENSION_DEMUX_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-extension-header.cc Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,597 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/header.h"
+#include "ipv6-extension-header.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6ExtensionHeader");
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHeader);
+
+TypeId Ipv6ExtensionHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionHeader")
+ .AddConstructor<Ipv6ExtensionHeader> ()
+ .SetParent<Header> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionHeader::Ipv6ExtensionHeader ()
+ : m_nextHeader (0),
+ m_length (0),
+ m_data (0)
+{
+}
+
+Ipv6ExtensionHeader::~Ipv6ExtensionHeader ()
+{
+}
+
+void Ipv6ExtensionHeader::SetNextHeader (uint8_t nextHeader)
+{
+ m_nextHeader = nextHeader;
+}
+
+uint8_t Ipv6ExtensionHeader::GetNextHeader () const
+{
+ return m_nextHeader;
+}
+
+void Ipv6ExtensionHeader::SetLength (uint16_t length)
+{
+ m_length = (length >> 3) - 1;
+}
+
+uint16_t Ipv6ExtensionHeader::GetLength () const
+{
+ return (m_length + 1) << 3;
+}
+
+void Ipv6ExtensionHeader::Print (std::ostream &os) const
+{
+ os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
+}
+
+uint32_t Ipv6ExtensionHeader::GetSerializedSize () const
+{
+ return 2;
+}
+
+void Ipv6ExtensionHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (m_nextHeader);
+ i.WriteU8 (m_length);
+ i.Write (m_data.PeekData (), m_data.GetSize ());
+}
+
+uint32_t Ipv6ExtensionHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ m_nextHeader = i.ReadU8 ();
+ m_length = i.ReadU8 ();
+
+ uint32_t dataLength = GetLength () - 2;
+ uint8_t data[dataLength];
+ i.Read (data, dataLength);
+
+ if (dataLength > m_data.GetSize ())
+ {
+ m_data.AddAtEnd (dataLength - m_data.GetSize ());
+ }
+ else
+ {
+ m_data.RemoveAtEnd (m_data.GetSize () - dataLength);
+ }
+
+ i = m_data.Begin ();
+ i.Write (data, dataLength);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHopByHopHeader);
+
+TypeId Ipv6ExtensionHopByHopHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionHopByHopHeader")
+ .AddConstructor<Ipv6ExtensionHopByHopHeader> ()
+ .SetParent<Ipv6ExtensionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionHopByHopHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader ()
+{
+}
+
+Ipv6ExtensionHopByHopHeader::~Ipv6ExtensionHopByHopHeader ()
+{
+}
+
+void Ipv6ExtensionHopByHopHeader::Print (std::ostream &os) const
+{
+ os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
+}
+
+uint32_t Ipv6ExtensionHopByHopHeader::GetSerializedSize () const
+{
+ return 2;
+}
+
+void Ipv6ExtensionHopByHopHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetNextHeader ());
+ i.WriteU8 ((GetLength () >> 3) - 1);
+}
+
+uint32_t Ipv6ExtensionHopByHopHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetNextHeader (i.ReadU8 ());
+ SetLength ((i.ReadU8 () + 1) << 3);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionDestinationHeader);
+
+TypeId Ipv6ExtensionDestinationHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionDestinationHeader")
+ .AddConstructor<Ipv6ExtensionDestinationHeader> ()
+ .SetParent<Ipv6ExtensionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionDestinationHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader ()
+{
+}
+
+Ipv6ExtensionDestinationHeader::~Ipv6ExtensionDestinationHeader ()
+{
+}
+
+void Ipv6ExtensionDestinationHeader::Print (std::ostream &os) const
+{
+ os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength () << " )";
+}
+
+uint32_t Ipv6ExtensionDestinationHeader::GetSerializedSize () const
+{
+ return 2;
+}
+
+void Ipv6ExtensionDestinationHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetNextHeader ());
+ i.WriteU8 ((GetLength () >> 3) - 1);
+}
+
+uint32_t Ipv6ExtensionDestinationHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetNextHeader (i.ReadU8 ());
+ SetLength ((i.ReadU8 () + 1) << 3);
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionFragmentHeader);
+
+TypeId Ipv6ExtensionFragmentHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragmentHeader")
+ .AddConstructor<Ipv6ExtensionFragmentHeader> ()
+ .SetParent<Ipv6ExtensionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionFragmentHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionFragmentHeader::Ipv6ExtensionFragmentHeader ()
+ : m_offset (0),
+ m_identification (0)
+{
+}
+
+Ipv6ExtensionFragmentHeader::~Ipv6ExtensionFragmentHeader ()
+{
+}
+
+void Ipv6ExtensionFragmentHeader::SetOffset (uint16_t offset)
+{
+ // Clear the offset, and save the MF bit
+ m_offset &= 1;
+ m_offset |= offset & (~7);
+}
+
+uint16_t Ipv6ExtensionFragmentHeader::GetOffset () const
+{
+ return m_offset & (~1);
+}
+
+void Ipv6ExtensionFragmentHeader::SetMoreFragment (bool moreFragment)
+{
+ m_offset = moreFragment ? m_offset | 1 : m_offset & (~1);
+}
+
+bool Ipv6ExtensionFragmentHeader::GetMoreFragment () const
+{
+ return m_offset & 1;
+}
+
+void Ipv6ExtensionFragmentHeader::SetIdentification (uint32_t identification)
+{
+ m_identification = identification;
+}
+
+uint32_t Ipv6ExtensionFragmentHeader::GetIdentification () const
+{
+ return m_identification;
+}
+
+void Ipv6ExtensionFragmentHeader::Print (std::ostream &os) const
+{
+ os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
+ << " offset = " << (uint32_t)GetOffset () << " MF = " << (uint32_t)GetMoreFragment () << " identification = " << (uint32_t)m_identification << " )";
+}
+
+uint32_t Ipv6ExtensionFragmentHeader::GetSerializedSize () const
+{
+ return 8;
+}
+
+void Ipv6ExtensionFragmentHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetNextHeader ());
+ i.WriteU8 ((GetLength () >> 3) - 1);
+ i.WriteHtonU16 (m_offset);
+ i.WriteHtonU32 (m_identification);
+}
+
+uint32_t Ipv6ExtensionFragmentHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetNextHeader (i.ReadU8 ());
+ SetLength ((i.ReadU8 () + 1) << 3);
+ m_offset = i.ReadNtohU16 ();
+ m_identification = i.ReadNtohU32 ();
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionRoutingHeader);
+
+TypeId Ipv6ExtensionRoutingHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingHeader")
+ .AddConstructor<Ipv6ExtensionRoutingHeader> ()
+ .SetParent<Ipv6ExtensionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionRoutingHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionRoutingHeader::Ipv6ExtensionRoutingHeader ()
+ : m_typeRouting (0),
+ m_segmentsLeft (0)
+{
+}
+
+Ipv6ExtensionRoutingHeader::~Ipv6ExtensionRoutingHeader ()
+{
+}
+
+void Ipv6ExtensionRoutingHeader::SetTypeRouting (uint8_t typeRouting)
+{
+ m_typeRouting = typeRouting;
+}
+
+uint8_t Ipv6ExtensionRoutingHeader::GetTypeRouting () const
+{
+ return m_typeRouting;
+}
+
+void Ipv6ExtensionRoutingHeader::SetSegmentsLeft (uint8_t segmentsLeft)
+{
+ m_segmentsLeft = segmentsLeft;
+}
+
+uint8_t Ipv6ExtensionRoutingHeader::GetSegmentsLeft () const
+{
+ return m_segmentsLeft;
+}
+
+void Ipv6ExtensionRoutingHeader::Print (std::ostream &os) const
+{
+ os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
+ << " typeRouting = " << (uint32_t)m_typeRouting << " segmentsLeft = " << (uint32_t)m_segmentsLeft << " )";
+}
+
+uint32_t Ipv6ExtensionRoutingHeader::GetSerializedSize () const
+{
+ return 4;
+}
+
+void Ipv6ExtensionRoutingHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetNextHeader ());
+ i.WriteU8 ((GetLength () >> 3) - 1);
+ i.WriteU8 (m_typeRouting);
+ i.WriteU8 (m_segmentsLeft);
+}
+
+uint32_t Ipv6ExtensionRoutingHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetNextHeader (i.ReadU8 ());
+ SetLength ((i.ReadU8 () + 1) << 3);
+ m_typeRouting = i.ReadU8 ();
+ m_segmentsLeft = i.ReadU8 ();
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionLooseRoutingHeader);
+
+TypeId Ipv6ExtensionLooseRoutingHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRoutingHeader")
+ .AddConstructor<Ipv6ExtensionLooseRoutingHeader> ()
+ .SetParent<Ipv6ExtensionRoutingHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionLooseRoutingHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionLooseRoutingHeader::Ipv6ExtensionLooseRoutingHeader ()
+ : m_routersAddress (0)
+{
+}
+
+Ipv6ExtensionLooseRoutingHeader::~Ipv6ExtensionLooseRoutingHeader ()
+{
+}
+
+void Ipv6ExtensionLooseRoutingHeader::SetNumberAddress (uint8_t n)
+{
+ m_routersAddress.clear ();
+ m_routersAddress.assign (n, Ipv6Address (""));
+}
+
+void Ipv6ExtensionLooseRoutingHeader::SetRoutersAddress (std::vector<Ipv6Address> routersAddress)
+{
+ m_routersAddress = routersAddress;
+}
+
+std::vector<Ipv6Address> Ipv6ExtensionLooseRoutingHeader::GetRoutersAddress () const
+{
+ return m_routersAddress;
+}
+
+void Ipv6ExtensionLooseRoutingHeader::SetRouterAddress (uint8_t index, Ipv6Address addr)
+{
+ m_routersAddress.at(index) = addr;
+}
+
+Ipv6Address Ipv6ExtensionLooseRoutingHeader::GetRouterAddress (uint8_t index) const
+{
+ return m_routersAddress.at (index);
+}
+
+void Ipv6ExtensionLooseRoutingHeader::Print (std::ostream &os) const
+{
+ os << "( nextHeader = " << (uint32_t)GetNextHeader () << " length = " << (uint32_t)GetLength ()
+ << " typeRouting = " << (uint32_t)GetTypeRouting () << " segmentsLeft = " << (uint32_t)GetSegmentsLeft () << " ";
+
+ for(std::vector<Ipv6Address>::const_iterator it = m_routersAddress.begin(); it != m_routersAddress.end(); it++)
+ {
+ os << *it << " ";
+ }
+
+ os << " )";
+}
+
+uint32_t Ipv6ExtensionLooseRoutingHeader::GetSerializedSize () const
+{
+ return 8 + m_routersAddress.size () * 16;
+}
+
+void Ipv6ExtensionLooseRoutingHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+ uint8_t buff[16];
+
+ i.WriteU8 (GetNextHeader ());
+ i.WriteU8 ((GetLength () >> 3) - 1);
+ i.WriteU8 (GetTypeRouting ());
+ i.WriteU8 (GetSegmentsLeft ());
+ i.WriteU32 (0);
+
+ for(VectorIpv6Address_t::const_iterator it = m_routersAddress.begin (); it != m_routersAddress.end () ; it++)
+ {
+ it->Serialize (buff);
+ i.Write (buff, 16);
+ }
+}
+
+uint32_t Ipv6ExtensionLooseRoutingHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+ uint8_t buff[16];
+
+ SetNextHeader (i.ReadU8 ());
+ SetLength ((i.ReadU8 () + 1) << 3);
+ SetTypeRouting (i.ReadU8 ());
+ SetSegmentsLeft (i.ReadU8 ());
+ i.ReadU32 ();
+
+ for(std::vector<Ipv6Address>::iterator it = m_routersAddress.begin(); it != m_routersAddress.end(); it++)
+ {
+ i.Read (buff, 16);
+ it->Set (buff);
+ }
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionESPHeader);
+
+TypeId Ipv6ExtensionESPHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionESPHeader")
+ .AddConstructor<Ipv6ExtensionESPHeader> ()
+ .SetParent<Ipv6ExtensionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionESPHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionESPHeader::Ipv6ExtensionESPHeader ()
+{
+}
+
+Ipv6ExtensionESPHeader::~Ipv6ExtensionESPHeader ()
+{
+}
+
+void Ipv6ExtensionESPHeader::Print (std::ostream &os) const
+{
+ /* TODO */
+}
+
+uint32_t Ipv6ExtensionESPHeader::GetSerializedSize () const
+{
+ /* TODO */
+ return 0;
+}
+
+void Ipv6ExtensionESPHeader::Serialize (Buffer::Iterator start) const
+{
+ /* TODO */
+}
+
+uint32_t Ipv6ExtensionESPHeader::Deserialize (Buffer::Iterator start)
+{
+ /* TODO */
+ return 0;
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionAHHeader);
+
+TypeId Ipv6ExtensionAHHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionAHHeader")
+ .AddConstructor<Ipv6ExtensionAHHeader> ()
+ .SetParent<Ipv6ExtensionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6ExtensionAHHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6ExtensionAHHeader::Ipv6ExtensionAHHeader ()
+{
+}
+
+Ipv6ExtensionAHHeader::~Ipv6ExtensionAHHeader ()
+{
+}
+
+void Ipv6ExtensionAHHeader::Print (std::ostream &os) const
+{
+ /* TODO */
+}
+
+uint32_t Ipv6ExtensionAHHeader::GetSerializedSize () const
+{
+ /* TODO */
+ return 0;
+}
+
+void Ipv6ExtensionAHHeader::Serialize (Buffer::Iterator start) const
+{
+ /* TODO */
+}
+
+uint32_t Ipv6ExtensionAHHeader::Deserialize (Buffer::Iterator start)
+{
+ /* TODO */
+ return 0;
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-extension-header.h Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,649 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#ifndef IPV6_EXTENSION_HEADER_H
+#define IPV6_EXTENSION_HEADER_H
+
+#include <vector>
+#include <ostream>
+
+#include "ns3/header.h"
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6ExtensionHeader
+ * \brief Header for IPv6 Extension.
+ */
+class Ipv6ExtensionHeader : public Header
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionHeader ();
+
+ /**
+ * \brief Set the "Next header" field.
+ * \param nextHeader the next header number
+ */
+ void SetNextHeader (uint8_t nextHeader);
+
+ /**
+ * \brief Get the next header.
+ * \return the next header number
+ */
+ uint8_t GetNextHeader () const;
+
+ /**
+ * brief Set the length of the extension.
+ * \param length the length of the extension in bytes
+ */
+ void SetLength (uint16_t length);
+
+ /**
+ * \brief Get the length of the extension.
+ * \return the length of the extension
+ */
+ uint16_t GetLength () const;
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The "next header" field.
+ */
+ uint8_t m_nextHeader;
+
+ /**
+ * \brief The "length" field.
+ */
+ uint8_t m_length;
+
+ /**
+ * \brief The data of the extension.
+ */
+ Buffer m_data;
+};
+
+/**
+ * \class Ipv6ExtensionHopByHopHeader
+ * \brief Header of IPv6 Extension "Hop by Hop"
+ */
+class Ipv6ExtensionHopByHopHeader : public Ipv6ExtensionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionHopByHopHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionHopByHopHeader ();
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+};
+
+/**
+ * \class Ipv6ExtensionDestinationHeader
+ * \brief Header of IPv6 Extension Destination
+ */
+class Ipv6ExtensionDestinationHeader : public Ipv6ExtensionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionDestinationHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionDestinationHeader ();
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+};
+
+/**
+ * \class Ipv6ExtensionFragmentHeader
+ * \brief Header of IPv6 Extension Fragment
+ */
+class Ipv6ExtensionFragmentHeader : public Ipv6ExtensionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionFragmentHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionFragmentHeader ();
+
+ /**
+ * \brief Set the "Offset" field.
+ * \param offset the offset of the fragment
+ */
+ void SetOffset (uint16_t offset);
+
+ /**
+ * \brief Get the field "Offset".
+ * \return the offset of the fragment
+ */
+ uint16_t GetOffset () const;
+
+ /**
+ * \brief Set the status of "More Fragment" bit.
+ * \param moreFragment the bit "More Fragment"
+ */
+ void SetMoreFragment (bool moreFragment);
+
+ /**
+ * \brief Get the status of "More Fragment" bit.
+ * \return the status of "More Fragment" bit.
+ */
+ bool GetMoreFragment () const;
+
+ /**
+ * \brief Set the "Identification" field.
+ * \param identification the identifier of the fragment
+ */
+ void SetIdentification (uint32_t identification);
+
+ /**
+ * \brief Get the field "Identification".
+ * \return the identifier of the fragment
+ */
+ uint32_t GetIdentification () const;
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief Offset of the fragment and More Fragment bit.
+ */
+ uint16_t m_offset;
+
+ /**
+ * \brief Identifier of the packet.
+ */
+ uint32_t m_identification;
+};
+
+/**
+ * \class Ipv6ExtensionRoutingHeader
+ * \brief Header of IPv6 Extension Routing
+ */
+class Ipv6ExtensionRoutingHeader : public Ipv6ExtensionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionRoutingHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionRoutingHeader ();
+
+ /**
+ * \brief Set the "Type of Routing" field.
+ * \param typeRouting the type of routing
+ */
+ void SetTypeRouting (uint8_t typeRouting);
+
+ /**
+ * \brief Get the field "Type of Routing".
+ * \return the type of routing
+ */
+ uint8_t GetTypeRouting () const;
+
+ /**
+ * \brief Set the "Segments left" field.
+ * \param segmentsLeft the number of segments left
+ */
+ void SetSegmentsLeft (uint8_t segmentsLeft);
+
+ /**
+ * \brief Get the field "Segments left".
+ * \return the number of segments left
+ */
+ uint8_t GetSegmentsLeft () const;
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief Type of routing.
+ */
+ uint8_t m_typeRouting;
+
+ /**
+ * \brief Number of left segments.
+ */
+ uint8_t m_segmentsLeft;
+};
+
+/**
+ * \class Ipv6ExtensionLooseRoutingHeader
+ * \brief Header of IPv6 Extension Routing : Type 0 (Loose Routing)
+ */
+class Ipv6ExtensionLooseRoutingHeader : public Ipv6ExtensionRoutingHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionLooseRoutingHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionLooseRoutingHeader ();
+
+ /**
+ * \brief Set the number of routers' address.
+ * \param n the number of routers' address
+ */
+ void SetNumberAddress (uint8_t n);
+
+ /**
+ * \brief Set the vector of routers' address
+ * \param routersAddress the vector of routers's address
+ */
+ void SetRoutersAddress (std::vector<Ipv6Address> routersAddress);
+
+ /**
+ * \brief Get the vector of routers' address
+ * \return the vector of routers' address
+ */
+ std::vector<Ipv6Address> GetRoutersAddress () const;
+
+ /**
+ * \brief Set a Router IPv6 Address.
+ * \param index the index of the IPv6 Address
+ * \param addr the new IPv6 Address
+ */
+ void SetRouterAddress (uint8_t index, Ipv6Address addr);
+
+ /**
+ * \brief Get a Router IPv6 Address.
+ * \param index the index of the IPv6 Address
+ * \return the router IPv6 Address
+ */
+ Ipv6Address GetRouterAddress (uint8_t index) const;
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief A vector of IPv6 Address.
+ */
+ typedef std::vector<Ipv6Address> VectorIpv6Address_t;
+
+ /**
+ * \brief The vector of Routers' IPv6 Address.
+ */
+ VectorIpv6Address_t m_routersAddress;
+};
+
+/**
+ * \class Ipv6ExtensionESPHeader
+ * \brief Header of IPv6 Extension ESP
+ */
+class Ipv6ExtensionESPHeader : public Ipv6ExtensionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionESPHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionESPHeader ();
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+};
+
+/**
+ * \class Ipv6ExtensionAHHeader
+ * \brief Header of IPv6 Extension AH
+ */
+class Ipv6ExtensionAHHeader : public Ipv6ExtensionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionAHHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionAHHeader ();
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+};
+
+} // namespace ns3
+
+#endif /* IPV6_EXTENSION_HEADER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-extension.cc Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,1047 @@
+/* Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#include <list>
+#include <ctime>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/uinteger.h"
+#include "ns3/object-vector.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/random-variable.h"
+#include "icmpv6-l4-protocol.h"
+#include "ipv6-extension-demux.h"
+#include "ipv6-extension.h"
+#include "ipv6-extension-header.h"
+#include "ipv6-option-demux.h"
+#include "ipv6-option.h"
+#include "udp-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6Extension");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6Extension);
+
+TypeId Ipv6Extension::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6Extension")
+ .SetParent<Object> ()
+ .AddAttribute ("ExtensionNumber", "The IPv6 extension number.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv6Extension::GetExtensionNumber),
+ MakeUintegerChecker<uint8_t> ())
+ .AddTraceSource ("Drop", "Drop ipv6 packet",
+ MakeTraceSourceAccessor (&Ipv6Extension::m_dropTrace))
+ ;
+ return tid;
+}
+
+Ipv6Extension::~Ipv6Extension ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6Extension::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+
+ m_node = node;
+}
+
+Ptr<Node> Ipv6Extension::GetNode () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return m_node;
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionHopByHop);
+
+const uint8_t Ipv6ExtensionHopByHop::EXT_NUMBER = 0;
+
+TypeId Ipv6ExtensionHopByHop::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionHopByHop")
+ .SetParent<Ipv6Extension> ()
+ .AddConstructor<Ipv6ExtensionHopByHop> ()
+ ;
+ return tid;
+}
+
+Ipv6ExtensionHopByHop::Ipv6ExtensionHopByHop ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ExtensionHopByHop::~Ipv6ExtensionHopByHop ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6ExtensionHopByHop::GetExtensionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return EXT_NUMBER;
+}
+
+uint8_t Ipv6ExtensionHopByHop::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+
+ // For ICMPv6 Error packets
+ Ptr<Packet> malformedPacket = packet->Copy();
+ malformedPacket->AddHeader(ipv6Header);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ipv6ExtensionHopByHopHeader hopbyhopHeader;
+ p->RemoveHeader (hopbyhopHeader);
+ if (nextHeader)
+ {
+ *nextHeader = hopbyhopHeader.GetNextHeader ();
+ }
+
+ Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+
+ Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode ()->GetObject<Ipv6OptionDemux> ();
+ Ptr<Ipv6Option> ipv6Option;
+
+ uint8_t totalSize = hopbyhopHeader.GetLength ();
+ uint8_t processedSize = hopbyhopHeader.GetSerializedSize ();
+ const uint8_t *data = p->PeekData ();
+ uint8_t optionType = 0;
+ uint8_t optionLength = 0;
+ isDropped = false;
+
+ while (totalSize > processedSize && !isDropped)
+ {
+ optionType = *(data + processedSize);
+ ipv6Option = ipv6OptionDemux->GetOption (optionType);
+
+ if (ipv6Option == 0)
+ {
+ optionType >>= 6;
+ switch (optionType)
+ {
+ case 0:
+ optionLength = *(data + processedSize + 1);
+ break;
+
+ case 1:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ case 2:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ /* TODO */
+ /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ case 3:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+
+ if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
+ {
+ /* TODO */
+ /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ }
+
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ else
+ {
+ optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, ipv6Interface, isDropped);
+ }
+
+ processedSize += optionLength;
+ p->RemoveAtStart (optionLength);
+ }
+
+ return processedSize;
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionDestination);
+
+const uint8_t Ipv6ExtensionDestination::EXT_NUMBER = 60;
+
+TypeId Ipv6ExtensionDestination::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionDestination")
+ .SetParent<Ipv6Extension> ()
+ .AddConstructor<Ipv6ExtensionDestination> ()
+ ;
+ return tid;
+}
+
+Ipv6ExtensionDestination::Ipv6ExtensionDestination ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ExtensionDestination::~Ipv6ExtensionDestination ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6ExtensionDestination::GetExtensionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return EXT_NUMBER;
+}
+
+uint8_t Ipv6ExtensionDestination::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+
+ // For ICMPv6 Error packets
+ Ptr<Packet> malformedPacket = packet->Copy();
+ malformedPacket->AddHeader(ipv6Header);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ipv6ExtensionDestinationHeader destinationHeader;
+ p->RemoveHeader (destinationHeader);
+ if (nextHeader)
+ {
+ *nextHeader = destinationHeader.GetNextHeader ();
+ }
+
+ Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+
+ Ptr<Ipv6OptionDemux> ipv6OptionDemux = GetNode ()->GetObject<Ipv6OptionDemux> ();
+ Ptr<Ipv6Option> ipv6Option;
+
+ uint8_t totalSize = destinationHeader.GetLength ();
+ uint8_t processedSize = destinationHeader.GetSerializedSize ();
+ const uint8_t *data = p->PeekData ();
+ uint8_t optionType = 0;
+ uint8_t optionLength = 0;
+ isDropped = false;
+
+ while (totalSize > processedSize && !isDropped)
+ {
+ optionType = *(data + processedSize);
+ ipv6Option = ipv6OptionDemux->GetOption (optionType);
+
+ if (ipv6Option == 0)
+ {
+ optionType >>= 6;
+ switch (optionType)
+ {
+ case 0:
+ optionLength = *(data + processedSize + 1);
+ break;
+
+ case 1:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ case 2:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+ /* TODO */
+ /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ case 3:
+ NS_LOG_LOGIC ("Unknown Option. Drop!");
+
+ if (!ipv6Header.GetDestinationAddress ().IsMulticast ())
+ {
+ /* TODO */
+ /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_UNKNOWN_OPTION, offset + processedSize); */
+ }
+
+ m_dropTrace (packet);
+ optionLength = 0;
+ isDropped = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ else
+ {
+ optionLength = ipv6Option->Process (packet, offset + processedSize, ipv6Header, ipv6Interface, isDropped);
+ }
+
+ processedSize += optionLength;
+ p->RemoveAtStart (optionLength);
+ }
+
+ return processedSize;
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionFragment);
+
+const uint8_t Ipv6ExtensionFragment::EXT_NUMBER = 44;
+
+TypeId Ipv6ExtensionFragment::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionFragment")
+ .SetParent<Ipv6Extension> ()
+ .AddConstructor<Ipv6ExtensionFragment> ()
+ ;
+ return tid;
+}
+
+Ipv6ExtensionFragment::Ipv6ExtensionFragment ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ExtensionFragment::~Ipv6ExtensionFragment ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6ExtensionFragment::DoDispose ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ for (MapFragments_t::iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
+ {
+ it->second = 0;
+ }
+
+ m_fragments.clear ();
+ Ipv6Extension::DoDispose ();
+}
+
+uint8_t Ipv6ExtensionFragment::GetExtensionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return EXT_NUMBER;
+}
+
+uint8_t Ipv6ExtensionFragment::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ipv6ExtensionFragmentHeader fragmentHeader;
+ p->RemoveHeader (fragmentHeader);
+
+ if (nextHeader)
+ {
+ *nextHeader = fragmentHeader.GetNextHeader ();
+ }
+
+ bool moreFragment = fragmentHeader.GetMoreFragment ();
+ uint16_t fragmentOffset = fragmentHeader.GetOffset ();
+ uint32_t identification = fragmentHeader.GetIdentification ();
+ Ipv6Address src = ipv6Header.GetSourceAddress ();
+
+ std::pair<Ipv6Address, uint32_t> fragmentsId = std::make_pair<Ipv6Address, uint32_t> (src, identification);
+ Ptr<Fragments> fragments;
+
+ MapFragments_t::iterator it = m_fragments.find (fragmentsId);
+ if (it == m_fragments.end ())
+ {
+ fragments = Create<Fragments> ();
+ m_fragments.insert (std::make_pair (fragmentsId, fragments));
+ }
+
+ else
+ {
+ fragments = it->second;
+ }
+
+ if (fragmentOffset == 0)
+ {
+ Ptr<Packet> unfragmentablePart = packet->Copy ();
+ unfragmentablePart->RemoveAtEnd (packet->GetSize () - offset);
+ fragments->SetUnfragmentablePart (unfragmentablePart);
+ }
+
+ fragments->AddFragment (p, fragmentOffset, moreFragment);
+
+ if (fragments->IsEntire ())
+ {
+ packet = fragments->GetPacket ();
+ isDropped = false;
+ }
+
+ else
+ {
+ NS_LOG_LOGIC("Fragment. Drop!");
+ m_dropTrace (packet);
+ isDropped = true;
+ }
+
+ return 0;
+}
+
+void Ipv6ExtensionFragment::GetFragments (Ptr<Packet> packet, uint32_t maxFragmentSize, std::list<Ptr<Packet> >& listFragments)
+{
+ Ptr<Packet> p = packet->Copy ();
+
+ Ipv6Header ipv6Header;
+ p->RemoveHeader (ipv6Header);
+
+ uint8_t nextHeader = ipv6Header.GetNextHeader ();
+ uint8_t ipv6HeaderSize = ipv6Header.GetSerializedSize ();
+
+ bool moreHeader = true;
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
+ {
+ moreHeader = false;
+ ipv6Header.SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
+
+ std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> > unfragmentablePart;
+ uint32_t unfragmentablePartSize = 0;
+
+ Ptr<Ipv6ExtensionDemux> extensionDemux = GetNode ()->GetObject<Ipv6ExtensionDemux> ();
+ Ptr<Ipv6Extension> extension = extensionDemux->GetExtension (nextHeader);
+ uint8_t extensionHeaderLength;
+
+ while (moreHeader)
+ {
+ if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+ {
+ Ipv6ExtensionHopByHopHeader *hopbyhopHeader = new Ipv6ExtensionHopByHopHeader();
+ p->RemoveHeader (*hopbyhopHeader);
+
+ nextHeader = hopbyhopHeader->GetNextHeader ();
+ extensionHeaderLength = hopbyhopHeader->GetLength ();
+
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
+ {
+ moreHeader = false;
+ hopbyhopHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
+
+ unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (hopbyhopHeader, Ipv6Header::IPV6_EXT_HOP_BY_HOP));
+ unfragmentablePartSize += extensionHeaderLength;
+ }
+ else if (nextHeader == Ipv6Header::IPV6_EXT_ROUTING)
+ {
+ uint8_t numberAddress = (*(p->PeekData() + 1)) / 2;
+ Ipv6ExtensionLooseRoutingHeader *routingHeader = new Ipv6ExtensionLooseRoutingHeader();
+ routingHeader->SetNumberAddress (numberAddress);
+ p->RemoveHeader (*routingHeader);
+
+ nextHeader = routingHeader->GetNextHeader ();
+ extensionHeaderLength = routingHeader->GetLength ();
+
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
+ {
+ moreHeader = false;
+ routingHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
+
+ unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (routingHeader, Ipv6Header::IPV6_EXT_ROUTING));
+ unfragmentablePartSize += extensionHeaderLength;
+ }
+ else if (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION)
+ {
+ Ipv6ExtensionDestinationHeader *destinationHeader = new Ipv6ExtensionDestinationHeader();
+ p->RemoveHeader (*destinationHeader);
+
+ nextHeader = destinationHeader->GetNextHeader ();
+ extensionHeaderLength = destinationHeader->GetLength ();
+
+ if (!(nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP || nextHeader == Ipv6Header::IPV6_EXT_ROUTING
+ || (nextHeader == Ipv6Header::IPV6_EXT_DESTINATION && *p->PeekData () == Ipv6Header::IPV6_EXT_ROUTING)))
+ {
+ moreHeader = false;
+ destinationHeader->SetNextHeader (Ipv6Header::IPV6_EXT_FRAGMENTATION);
+ }
+
+ unfragmentablePart.push_back (std::make_pair<Ipv6ExtensionHeader *, uint8_t> (destinationHeader, Ipv6Header::IPV6_EXT_DESTINATION));
+ unfragmentablePartSize += extensionHeaderLength;
+ }
+ }
+
+ Ipv6ExtensionFragmentHeader fragmentHeader;
+ uint8_t fragmentHeaderSize = fragmentHeader.GetSerializedSize ();
+
+ uint32_t maxFragmentablePartSize = maxFragmentSize - ipv6HeaderSize - unfragmentablePartSize - fragmentHeaderSize;
+ uint32_t currentFragmentablePartSize = 0;
+
+ bool moreFragment = true;
+ UniformVariable uvar;
+ uint32_t identification = (uint32_t) uvar.GetValue(0, (uint32_t)-1);
+ uint16_t offset = 0;
+
+ do
+ {
+ if (p->GetSize () > offset + maxFragmentablePartSize)
+ {
+ moreFragment = true;
+ currentFragmentablePartSize = maxFragmentablePartSize;
+ }
+ else
+ {
+ moreFragment = false;
+ currentFragmentablePartSize = p->GetSize () - offset;
+ }
+
+ currentFragmentablePartSize -= currentFragmentablePartSize % 8;
+
+ fragmentHeader.SetNextHeader (nextHeader);
+ fragmentHeader.SetLength (currentFragmentablePartSize);
+ fragmentHeader.SetOffset (offset);
+ fragmentHeader.SetMoreFragment (moreFragment);
+ fragmentHeader.SetIdentification (identification);
+
+ Ptr<Packet> fragment = p->CreateFragment (offset, currentFragmentablePartSize);
+ offset += currentFragmentablePartSize;
+
+ fragment->AddHeader (fragmentHeader);
+
+ for (std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
+ {
+ if(it->second == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+ {
+ fragment->AddHeader (*dynamic_cast<Ipv6ExtensionHopByHopHeader *>(it->first));
+ }
+ else if(it->second == Ipv6Header::IPV6_EXT_ROUTING)
+ {
+ fragment->AddHeader (*dynamic_cast<Ipv6ExtensionLooseRoutingHeader *>(it->first));
+ }
+ else if(it->second == Ipv6Header::IPV6_EXT_DESTINATION)
+ {
+ fragment->AddHeader (*dynamic_cast<Ipv6ExtensionDestinationHeader *>(it->first));
+ }
+ }
+
+ ipv6Header.SetPayloadLength (fragment->GetSize());
+ fragment->AddHeader (ipv6Header);
+
+ std::ostringstream oss;
+ fragment->Print(oss);
+ listFragments.push_back (fragment);
+ } while (moreFragment);
+
+ for (std::list<std::pair<Ipv6ExtensionHeader *, uint8_t> >::iterator it = unfragmentablePart.begin (); it != unfragmentablePart.end (); it++)
+ {
+ delete it->first;
+ }
+
+ unfragmentablePart.clear();
+}
+
+ Ipv6ExtensionFragment::Fragments::Fragments ()
+: m_moreFragment (0),
+ m_refCount (1)
+{
+}
+
+Ipv6ExtensionFragment::Fragments::~Fragments ()
+{
+}
+
+void Ipv6ExtensionFragment::Fragments::Ref () const
+{
+ m_refCount++;
+}
+
+void Ipv6ExtensionFragment::Fragments::Unref () const
+{
+ m_refCount--;
+
+ if (m_refCount == 0)
+ {
+ delete this;
+ }
+}
+
+void Ipv6ExtensionFragment::Fragments::AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment)
+{
+ std::list<std::pair<Ptr<Packet>, uint16_t> >::iterator it;
+
+ for (it = m_fragments.begin (); it != m_fragments.end (); it++)
+ {
+ if (it->second > fragmentOffset)
+ {
+ break;
+ }
+ }
+
+ if (it == m_fragments.end ())
+ {
+ m_moreFragment = moreFragment;
+ }
+
+ m_fragments.insert (it, std::make_pair<Ptr<Packet>, uint16_t> (fragment, fragmentOffset));
+}
+
+void Ipv6ExtensionFragment::Fragments::SetUnfragmentablePart (Ptr<Packet> unfragmentablePart)
+{
+ m_unfragmentable = unfragmentablePart;
+}
+
+bool Ipv6ExtensionFragment::Fragments::IsEntire () const
+{
+ bool ret = !m_moreFragment && m_fragments.size () > 0;
+
+ if (ret)
+ {
+ uint16_t lastEndOffset = 0;
+
+ for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
+ {
+ if (lastEndOffset != it->second)
+ {
+ ret = false;
+ break;
+ }
+
+ lastEndOffset += it->first->GetSize ();
+ }
+ }
+
+ return ret;
+}
+
+Ptr<Packet> Ipv6ExtensionFragment::Fragments::GetPacket () const
+{
+ Ptr<Packet> p = m_unfragmentable->Copy ();
+
+ for (std::list<std::pair<Ptr<Packet>, uint16_t> >::const_iterator it = m_fragments.begin (); it != m_fragments.end (); it++)
+ {
+ p->AddAtEnd(it->first);
+ }
+
+ /* XXX : FIX THIS BUG (NS_ASSERT WHEN PRINT PACKET INFORMATION */
+ /*
+ std::ostringstream oss;
+ p->Print(oss);
+ std::cout << oss.str() << std::endl;
+ */
+
+ return p;
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionRouting);
+
+const uint8_t Ipv6ExtensionRouting::EXT_NUMBER = 43;
+
+TypeId Ipv6ExtensionRouting::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionRouting")
+ .SetParent<Ipv6Extension> ()
+ .AddConstructor<Ipv6ExtensionRouting> ()
+ ;
+ return tid;
+}
+
+Ipv6ExtensionRouting::Ipv6ExtensionRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ExtensionRouting::~Ipv6ExtensionRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6ExtensionRouting::GetExtensionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return EXT_NUMBER;
+}
+
+uint8_t Ipv6ExtensionRouting::GetTypeRouting () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ return 0;
+}
+
+uint8_t Ipv6ExtensionRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+
+ // For ICMPv6 Error Packets
+ Ptr<Packet> malformedPacket = packet->Copy();
+ malformedPacket->AddHeader(ipv6Header);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ const uint8_t *buff = packet->PeekData ();
+
+ uint8_t routingNextHeader = *buff;
+ uint8_t routingLength = *(buff+1);
+ uint8_t routingTypeRouting = *(buff+2);
+ uint8_t routingSegmentsLeft = *(buff+3);
+
+ if (nextHeader)
+ {
+ *nextHeader = routingNextHeader;
+ }
+
+ Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+
+ Ptr<Ipv6ExtensionRoutingDemux> ipv6ExtensionRoutingDemux = GetNode ()->GetObject<Ipv6ExtensionRoutingDemux> ();
+ Ptr<Ipv6ExtensionRouting> ipv6ExtensionRouting = ipv6ExtensionRoutingDemux->GetExtensionRouting (routingTypeRouting);
+
+ if (ipv6ExtensionRouting == 0)
+ {
+ if (routingSegmentsLeft == 0)
+ {
+ isDropped = false;
+ }
+
+ else
+ {
+ NS_LOG_LOGIC("Malformed header. Drop!");
+
+ /* TODO */
+ /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1); */
+ m_dropTrace (packet);
+ isDropped = true;
+ }
+
+ return routingLength;
+ }
+
+ return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, ipv6Interface, (uint8_t *)0, isDropped);
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionRoutingDemux);
+
+TypeId Ipv6ExtensionRoutingDemux::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionRoutingDemux")
+ .SetParent<Object> ()
+ .AddAttribute ("Routing Extensions", "The set of IPv6 Routing extensions registered with this demux.",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&Ipv6ExtensionRoutingDemux::m_extensionsRouting),
+ MakeObjectVectorChecker<Ipv6ExtensionRouting> ())
+ ;
+ return tid;
+}
+
+Ipv6ExtensionRoutingDemux::Ipv6ExtensionRoutingDemux ()
+{
+}
+
+Ipv6ExtensionRoutingDemux::~Ipv6ExtensionRoutingDemux ()
+{
+}
+
+void Ipv6ExtensionRoutingDemux::DoDispose ()
+{
+ for (Ipv6ExtensionRoutingList_t::iterator it = m_extensionsRouting.begin (); it != m_extensionsRouting.end (); it++)
+ {
+ (*it)->Dispose ();
+ *it = 0;
+ }
+ m_extensionsRouting.clear ();
+ m_node = 0;
+ Object::DoDispose ();
+}
+
+void Ipv6ExtensionRoutingDemux::SetNode (Ptr<Node> node)
+{
+ m_node = node;
+}
+
+void Ipv6ExtensionRoutingDemux::Insert (Ptr<Ipv6ExtensionRouting> extensionRouting)
+{
+ m_extensionsRouting.push_back (extensionRouting);
+}
+
+Ptr<Ipv6ExtensionRouting> Ipv6ExtensionRoutingDemux::GetExtensionRouting (uint8_t typeRouting)
+{
+ for (Ipv6ExtensionRoutingList_t::iterator i = m_extensionsRouting.begin (); i != m_extensionsRouting.end (); i++)
+ {
+ if ((*i)->GetTypeRouting () == typeRouting)
+ {
+ return *i;
+ }
+ }
+ return 0;
+}
+
+void Ipv6ExtensionRoutingDemux::Remove (Ptr<Ipv6ExtensionRouting> extensionRouting)
+{
+ m_extensionsRouting.remove (extensionRouting);
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionLooseRouting);
+
+const uint8_t Ipv6ExtensionLooseRouting::TYPE_ROUTING = 0;
+
+TypeId Ipv6ExtensionLooseRouting::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionLooseRouting")
+ .SetParent<Ipv6ExtensionRouting> ()
+ .AddConstructor<Ipv6ExtensionLooseRouting> ()
+ ;
+ return tid;
+}
+
+Ipv6ExtensionLooseRouting::Ipv6ExtensionLooseRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ExtensionLooseRouting::~Ipv6ExtensionLooseRouting ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6ExtensionLooseRouting::GetTypeRouting () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return TYPE_ROUTING;
+}
+
+uint8_t Ipv6ExtensionLooseRouting::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+
+ // For ICMPv6 Error packets
+ Ptr<Packet> malformedPacket = packet->Copy ();
+ malformedPacket->AddHeader (ipv6Header);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ // Copy IPv6 Header : ipv6Header -> ipv6header
+ Buffer tmp;
+ tmp.AddAtStart (ipv6Header.GetSerializedSize ());
+ Buffer::Iterator it = tmp.Begin ();
+ Ipv6Header ipv6header;
+ ipv6Header.Serialize (it);
+ ipv6header.Deserialize (it);
+
+ // Get the number of routers' address field
+ uint8_t numberAddress = (*(p->PeekData() + 1)) / 2;
+ Ipv6ExtensionLooseRoutingHeader routingHeader;
+ routingHeader.SetNumberAddress (numberAddress);
+ p->RemoveHeader (routingHeader);
+
+ if (nextHeader)
+ {
+ *nextHeader = routingHeader.GetNextHeader ();
+ }
+
+ Ptr<Icmpv6L4Protocol> icmpv6 = GetNode ()->GetObject<Ipv6L3Protocol> ()->GetIcmpv6 ();
+
+ Ipv6Address srcAddress = ipv6header.GetSourceAddress ();
+ Ipv6Address destAddress = ipv6header.GetDestinationAddress ();
+ uint8_t hopLimit = ipv6header.GetHopLimit ();
+ uint8_t segmentsLeft = routingHeader.GetSegmentsLeft ();
+ uint8_t length = (routingHeader.GetLength () >> 3) - 1;
+ uint8_t nbAddress = length / 2;
+ uint8_t nextAddressIndex;
+ Ipv6Address nextAddress;
+
+
+ if (segmentsLeft == 0)
+ {
+ isDropped = false;
+ return routingHeader.GetSerializedSize ();
+ }
+
+ if (length % 2 != 0)
+ {
+ NS_LOG_LOGIC("Malformed header. Drop!");
+ /* TODO */
+ /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1); */
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
+
+ if (segmentsLeft > nbAddress)
+ {
+ NS_LOG_LOGIC("Malformed header. Drop!");
+ /* TODO */
+ /* icmpv6->SendErrorParameterError (malformedPacket, ipv6Interface->GetAddress(), srcAddress, Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 3); */
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
+
+ routingHeader.SetSegmentsLeft (segmentsLeft - 1);
+ nextAddressIndex = nbAddress - segmentsLeft;
+ nextAddress = routingHeader.GetRouterAddress (nextAddressIndex);
+
+ if (nextAddress.IsMulticast () || destAddress.IsMulticast ())
+ {
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
+
+ routingHeader.SetRouterAddress (nextAddressIndex, destAddress);
+ ipv6header.SetDestinationAddress (nextAddress);
+
+ if (hopLimit <= 1)
+ {
+ NS_LOG_LOGIC("Time Exceeded : Hop Limit <= 1. Drop!");
+ /* TODO */
+ /* icmpv6->SendErrorTimeExceeded (malformedPacket, ipv6Interface->GetAddress(), srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT); */
+ m_dropTrace (packet);
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+ }
+
+ routingHeader.SetLength(88);
+ ipv6header.SetHopLimit (hopLimit - 1);
+ p->AddHeader (routingHeader);
+
+ /* TODO */
+/*
+ uint32_t ifIndex;
+ Ptr<Ipv6L3Protocol> ipv6 = GetNode ()->GetObject<Ipv6L3Protocol> ();
+
+ if (ipv6->GetIfIndexForDestination (nextAddress, ifIndex))
+ {
+ ipv6->Lookup (ipv6header, p, MakeCallback (&Ipv6L3Protocol::SendRealOut, PeekPointer (ipv6)));
+ }
+*/
+ isDropped = true;
+ return routingHeader.GetSerializedSize ();
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionESP);
+
+const uint8_t Ipv6ExtensionESP::EXT_NUMBER = 50;
+
+TypeId Ipv6ExtensionESP::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionESP")
+ .SetParent<Ipv6Extension> ()
+ .AddConstructor<Ipv6ExtensionESP> ()
+ ;
+ return tid;
+}
+
+Ipv6ExtensionESP::Ipv6ExtensionESP ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ExtensionESP::~Ipv6ExtensionESP ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6ExtensionESP::GetExtensionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return EXT_NUMBER;
+}
+
+uint8_t Ipv6ExtensionESP::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+
+ /* TODO */
+
+ return 0;
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6ExtensionAH);
+
+const uint8_t Ipv6ExtensionAH::EXT_NUMBER = 51;
+
+TypeId Ipv6ExtensionAH::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6ExtensionAH")
+ .SetParent<Ipv6Extension> ()
+ .AddConstructor<Ipv6ExtensionAH> ()
+ ;
+ return tid;
+}
+
+Ipv6ExtensionAH::Ipv6ExtensionAH ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6ExtensionAH::~Ipv6ExtensionAH ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6ExtensionAH::GetExtensionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return EXT_NUMBER;
+}
+
+uint8_t Ipv6ExtensionAH::Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << nextHeader << isDropped);
+
+ /* TODO */
+
+ return true;
+}
+} /* namespace ns3 */
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-extension.h Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,591 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#ifndef IPV6_EXTENSION_H
+#define IPV6_EXTENSION_H
+
+#include <map>
+#include <list>
+
+#include "ns3/object.h"
+#include "ns3/node.h"
+#include "ns3/ptr.h"
+#include "ipv6-interface.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/buffer.h"
+#include "ns3/packet.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/traced-callback.h"
+
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6Extension
+ * \brief IPv6 Extension base
+ * If you want to implement a new IPv6 extension, all you have to do is
+ * implement a subclass of this class and add it to an Ipv6ExtensionDemux.
+ */
+class Ipv6Extension : public Object
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6Extension ();
+
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Get the node.
+ * \return the node
+ */
+ Ptr<Node> GetNode () const;
+
+ /**
+ * \brief Get the extension number.
+ * \return extension number
+ */
+ virtual uint8_t GetExtensionNumber () const = 0;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ *
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped) = 0;
+
+ protected:
+ TracedCallback<Ptr<const Packet> > m_dropTrace;
+
+ private:
+ /**
+ * \brief The node.
+ */
+ Ptr<Node> m_node;
+};
+
+/**
+ * \class Ipv6ExtensionHopByHop
+ * \brief IPv6 Extension "Hop By Hop"
+ */
+class Ipv6ExtensionHopByHop : public Ipv6Extension
+{
+ public:
+ static const uint8_t EXT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionHopByHop ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6ExtensionHopByHop ();
+
+ /**
+ * \brief Get the extension number.
+ * \return extension number
+ */
+ virtual uint8_t GetExtensionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+};
+
+/**
+ * \class Ipv6ExtensionDestination
+ * \brief IPv6 Extension Destination
+ */
+class Ipv6ExtensionDestination : public Ipv6Extension
+{
+ public:
+ static const uint8_t EXT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionDestination ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6ExtensionDestination ();
+
+ /**
+ * \brief Get the extension number.
+ * \return extension number
+ */
+ virtual uint8_t GetExtensionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+};
+
+/**
+ * \class Ipv6ExtensionFragment
+ * \brief IPv6 Extension Fragment
+ */
+class Ipv6ExtensionFragment : public Ipv6Extension
+{
+ public:
+ static const uint8_t EXT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionFragment ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6ExtensionFragment ();
+
+ /**
+ * \brief Get the extension number.
+ * \return extension number
+ */
+ virtual uint8_t GetExtensionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+
+ /**
+ * \brief Fragment a packet
+ * \param packet the packet
+ * \param fragmentSize the maximal size of the fragment (unfragmentable part + fragmentation header + fragmentable part)
+ * \param listFragments the list of fragments
+ */
+ void GetFragments (Ptr<Packet> packet, uint32_t fragmentSize, std::list<Ptr<Packet> >& listFragments);
+
+ protected:
+ /**
+ * \brief Dispose this object.
+ */
+ virtual void DoDispose ();
+
+ private:
+ /**
+ * \class Fragments
+ * \brief A Set of Fragment
+ */
+ class Fragments
+ {
+ public:
+ /**
+ * \brief Constructor.
+ */
+ Fragments ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Fragments ();
+
+ void Ref () const;
+ void Unref () const;
+
+ /**
+ * \brief Add a fragment.
+ * \param fragment the fragment
+ * \param fragmentOffset the offset of the fragment
+ * \param moreFragment the bit "More Fragment"
+ */
+ void AddFragment (Ptr<Packet> fragment, uint16_t fragmentOffset, bool moreFragment);
+
+ /**
+ * \brief Set the unfragmentable part of the packet.
+ * \param unfragmentablePart the unfragmentable part
+ */
+ void SetUnfragmentablePart (Ptr<Packet> unfragmentablePart);
+
+ /**
+ * \brief If all fragments have been added.
+ * \returns true if the packet is entire
+ */
+ bool IsEntire () const;
+
+ /**
+ * \brief Get the entire packet.
+ * \return the entire packet
+ */
+ Ptr<Packet> GetPacket () const;
+
+ private:
+ /**
+ * \brief If other fragments will be sent.
+ */
+ bool m_moreFragment;
+
+ /**
+ * \brief The current fragments.
+ */
+ std::list<std::pair<Ptr<Packet>, uint16_t> > m_fragments;
+
+ /**
+ * \brief The unfragmentable part.
+ */
+ Ptr<Packet> m_unfragmentable;
+
+ /**
+ * \brief Number of references.
+ */
+ mutable uint32_t m_refCount;
+ };
+
+ typedef std::map<std::pair<Ipv6Address, uint32_t>, Ptr<Fragments> > MapFragments_t;
+
+ /**
+ * \brief The hash of fragmented packets.
+ */
+ MapFragments_t m_fragments;
+};
+
+/**
+ * \class Ipv6ExtensionRouting
+ * \brief IPv6 Extension Routing
+ * If you want to implement a new IPv6 routing extension, all you have to do is
+ * implement a subclass of this class and add it to an Ipv6ExtensionRoutingDemux.
+ */
+class Ipv6ExtensionRouting : public Ipv6Extension
+{
+ public:
+ static const uint8_t EXT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionRouting ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6ExtensionRouting ();
+
+ /**
+ * \brief Get the extension number.
+ * \return extension number
+ */
+ virtual uint8_t GetExtensionNumber () const;
+
+ /**
+ * \brief Get the type of routing.
+ * \return type of routing
+ */
+ virtual uint8_t GetTypeRouting () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ *
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+};
+
+/**
+ * \class Ipv6ExtensionRoutingDemux
+ * \brief IPv6 Extension Routing Demux.
+ */
+class Ipv6ExtensionRoutingDemux : public Object
+{
+ public:
+ /**
+ * \brief The interface ID.
+ * \return type ID
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionRoutingDemux ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6ExtensionRoutingDemux ();
+
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Insert a new IPv6 Routing Extension.
+ * \param extensionRouting the routing extension to insert
+ */
+ void Insert (Ptr<Ipv6ExtensionRouting> extensionRouting);
+
+ /**
+ * \brief Get the routing extension corresponding to typeRouting.
+ * \param typeRouting the number of the routing extension to retrieve
+ * \return a matching IPv6 routing extension
+ */
+ Ptr<Ipv6ExtensionRouting> GetExtensionRouting (uint8_t typeRouting);
+
+ /**
+ * \brief Remove a routing extension from this demux.
+ * \param extensionRouting pointer on the extension to remove
+ */
+ void Remove (Ptr<Ipv6ExtensionRouting> extensionRouting);
+
+ protected:
+ /**
+ * \brief Dispose this object.
+ */
+ virtual void DoDispose();
+
+ private:
+ typedef std::list<Ptr<Ipv6ExtensionRouting> > Ipv6ExtensionRoutingList_t;
+
+ /**
+ * \brief List of IPv6 Routing Extensions supported.
+ */
+ Ipv6ExtensionRoutingList_t m_extensionsRouting;
+
+ /**
+ * \brief The node.
+ */
+ Ptr<Node> m_node;
+};
+
+/**
+ * \class Ipv6ExtensionLooseRouting
+ * \brief IPv6 Extension Loose Routing
+ */
+class Ipv6ExtensionLooseRouting : public Ipv6ExtensionRouting
+{
+ public:
+ static const uint8_t TYPE_ROUTING;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionLooseRouting ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6ExtensionLooseRouting ();
+
+ /**
+ * \brief Get the type of routing.
+ * \return type of routing
+ */
+ virtual uint8_t GetTypeRouting () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ *
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+};
+
+/**
+ * \class Ipv6ExtensionESP
+ * \brief IPv6 Extension ESP (Encapsulating Security Payload)
+ */
+class Ipv6ExtensionESP : public Ipv6Extension
+{
+ public:
+ static const uint8_t EXT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionESP ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6ExtensionESP ();
+
+ /**
+ * \brief Get the extension number.
+ * \return extension number
+ */
+ virtual uint8_t GetExtensionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ *
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+};
+
+/**
+ * \class Ipv6ExtensionAH
+ * \brief IPv6 Extension AH (Authentication Header)
+ */
+class Ipv6ExtensionAH : public Ipv6Extension
+{
+ public:
+ static const uint8_t EXT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6ExtensionAH ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6ExtensionAH ();
+
+ /**
+ * \brief Get the extension number.
+ * \return extension number
+ */
+ virtual uint8_t GetExtensionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ *
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param nextHeader the next header
+ * \param isDropped if the packet must be dropped
+ * \return the size processed
+ */
+ virtual uint8_t Process (Ptr<Packet>& packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, uint8_t *nextHeader, bool& isDropped);
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_EXTENSION_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-option-demux.cc Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#include <sstream>
+#include "ns3/node.h"
+#include "ns3/ptr.h"
+#include "ns3/object-vector.h"
+#include "ipv6-option-demux.h"
+#include "ipv6-option.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionDemux);
+
+TypeId Ipv6OptionDemux::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionDemux")
+ .SetParent<Object> ()
+ .AddAttribute ("Options", "The set of IPv6 options registered with this demux.",
+ ObjectVectorValue (),
+ MakeObjectVectorAccessor (&Ipv6OptionDemux::m_options),
+ MakeObjectVectorChecker<Ipv6Option> ())
+ ;
+ return tid;
+}
+
+Ipv6OptionDemux::Ipv6OptionDemux ()
+{
+}
+
+Ipv6OptionDemux::~Ipv6OptionDemux ()
+{
+}
+
+void Ipv6OptionDemux::DoDispose ()
+{
+ for (Ipv6OptionList_t::iterator it = m_options.begin (); it != m_options.end (); it++)
+ {
+ (*it)->Dispose ();
+ *it = 0;
+ }
+ m_options.clear ();
+ m_node = 0;
+ Object::DoDispose ();
+}
+
+void Ipv6OptionDemux::SetNode (Ptr<Node> node)
+{
+ m_node = node;
+}
+
+void Ipv6OptionDemux::Insert (Ptr<Ipv6Option> option)
+{
+ m_options.push_back (option);
+}
+
+Ptr<Ipv6Option> Ipv6OptionDemux::GetOption (int optionNumber)
+{
+ for (Ipv6OptionList_t::iterator i = m_options.begin (); i != m_options.end (); ++i)
+ {
+ if ((*i)->GetOptionNumber () == optionNumber)
+ {
+ return *i;
+ }
+ }
+ return 0;
+}
+
+void Ipv6OptionDemux::Remove (Ptr<Ipv6Option> option)
+{
+ m_options.remove (option);
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-option-demux.h Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#ifndef IPV6_OPTION_DEMUX_H
+#define IPV6_OPTION_DEMUX_H
+
+#include <list>
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
+namespace ns3
+{
+
+class Ipv6Option;
+class Node;
+
+/**
+ * \class Ipv6OptionDemux
+ * \brief IPv6 Option Demux.
+ */
+class Ipv6OptionDemux : public Object
+{
+ public:
+ /**
+ * \brief The interface ID.
+ * \return type ID
+ */
+ static TypeId GetTypeId (void);
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionDemux ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6OptionDemux ();
+
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Insert a new IPv6 Option.
+ * \param option the option to insert
+ */
+ void Insert (Ptr<Ipv6Option> option);
+
+ /**
+ * \brief Get the option corresponding to optionNumber.
+ * \param optionNumber the option number of the option to retrieve
+ * \return a matching IPv6 option
+ */
+ Ptr<Ipv6Option> GetOption (int optionNumber);
+
+ /**
+ * \brief Remove an option from this demux.
+ * \param option pointer on the option to remove
+ */
+ void Remove (Ptr<Ipv6Option> option);
+
+ protected:
+ /**
+ * \brief Dispose this object.
+ */
+ virtual void DoDispose();
+
+ private:
+ typedef std::list<Ptr<Ipv6Option> > Ipv6OptionList_t;
+
+ /**
+ * \brief List of IPv6 Options supported.
+ */
+ Ipv6OptionList_t m_options;
+
+ /**
+ * \brief The node.
+ */
+ Ptr<Node> m_node;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_OPTION_DEMUX_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-option-header.cc Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,342 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/header.h"
+#include "ipv6-option-header.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6OptionHeader");
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionHeader);
+
+TypeId Ipv6OptionHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionHeader")
+ .AddConstructor<Ipv6OptionHeader> ()
+ .SetParent<Header> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6OptionHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6OptionHeader::Ipv6OptionHeader ()
+ : m_type (0),
+ m_length (0)
+{
+}
+
+Ipv6OptionHeader::~Ipv6OptionHeader ()
+{
+}
+
+void Ipv6OptionHeader::SetType (uint8_t type)
+{
+ m_type = type;
+}
+
+uint8_t Ipv6OptionHeader::GetType () const
+{
+ return m_type;
+}
+
+void Ipv6OptionHeader::SetLength (uint8_t length)
+{
+ m_length = length;
+}
+
+uint8_t Ipv6OptionHeader::GetLength () const
+{
+ return m_length;
+}
+
+void Ipv6OptionHeader::Print (std::ostream &os) const
+{
+ os << "( type = " << (uint32_t)m_type << " )";
+}
+
+uint32_t Ipv6OptionHeader::GetSerializedSize () const
+{
+ return 1;
+}
+
+void Ipv6OptionHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (m_type);
+}
+
+uint32_t Ipv6OptionHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ m_type = i.ReadU8 ();
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionPad1Header);
+
+TypeId Ipv6OptionPad1Header::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionPad1Header")
+ .AddConstructor<Ipv6OptionPad1Header> ()
+ .SetParent<Ipv6OptionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6OptionPad1Header::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6OptionPad1Header::Ipv6OptionPad1Header ()
+{
+}
+
+Ipv6OptionPad1Header::~Ipv6OptionPad1Header ()
+{
+}
+
+void Ipv6OptionPad1Header::Print (std::ostream &os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " )";
+}
+
+uint32_t Ipv6OptionPad1Header::GetSerializedSize () const
+{
+ return 1;
+}
+
+void Ipv6OptionPad1Header::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+}
+
+uint32_t Ipv6OptionPad1Header::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionPadnHeader);
+
+TypeId Ipv6OptionPadnHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionPadnHeader")
+ .AddConstructor<Ipv6OptionPadnHeader> ()
+ .SetParent<Ipv6OptionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6OptionPadnHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6OptionPadnHeader::Ipv6OptionPadnHeader ()
+{
+}
+
+Ipv6OptionPadnHeader::~Ipv6OptionPadnHeader ()
+{
+}
+
+void Ipv6OptionPadnHeader::Print (std::ostream &os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " )";
+}
+
+uint32_t Ipv6OptionPadnHeader::GetSerializedSize () const
+{
+ return GetLength () + 2;
+}
+
+void Ipv6OptionPadnHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetLength ());
+
+ for(int padding = 0; padding < GetLength (); padding++)
+ {
+ i.WriteU8 (0);
+ }
+}
+
+uint32_t Ipv6OptionPadnHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetLength (i.ReadU8 ());
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionJumbogramHeader);
+
+TypeId Ipv6OptionJumbogramHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionJumbogramHeader")
+ .AddConstructor<Ipv6OptionJumbogramHeader> ()
+ .SetParent<Ipv6OptionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6OptionJumbogramHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6OptionJumbogramHeader::Ipv6OptionJumbogramHeader ()
+{
+ SetLength (4);
+}
+
+Ipv6OptionJumbogramHeader::~Ipv6OptionJumbogramHeader ()
+{
+}
+
+void Ipv6OptionJumbogramHeader::SetDataLength (uint32_t dataLength)
+{
+ m_dataLength = dataLength;
+}
+
+uint32_t Ipv6OptionJumbogramHeader::GetDataLength () const
+{
+ return m_dataLength;
+}
+
+void Ipv6OptionJumbogramHeader::Print (std::ostream &os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " data length = " << (uint32_t)m_dataLength << " )";
+}
+
+uint32_t Ipv6OptionJumbogramHeader::GetSerializedSize () const
+{
+ return GetLength () + 2;
+}
+
+void Ipv6OptionJumbogramHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetLength ());
+ i.WriteHtonU16 (m_dataLength);
+}
+
+uint32_t Ipv6OptionJumbogramHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetLength (i.ReadU8 ());
+ m_dataLength = i.ReadNtohU16 ();
+
+ return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionRouterAlertHeader);
+
+TypeId Ipv6OptionRouterAlertHeader::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionRouterAlertHeader")
+ .AddConstructor<Ipv6OptionRouterAlertHeader> ()
+ .SetParent<Ipv6OptionHeader> ()
+ ;
+ return tid;
+}
+
+TypeId Ipv6OptionRouterAlertHeader::GetInstanceTypeId () const
+{
+ return GetTypeId ();
+}
+
+Ipv6OptionRouterAlertHeader::Ipv6OptionRouterAlertHeader ()
+ : m_value (0)
+{
+ SetLength (2);
+}
+
+Ipv6OptionRouterAlertHeader::~Ipv6OptionRouterAlertHeader ()
+{
+}
+
+void Ipv6OptionRouterAlertHeader::SetValue (uint16_t value)
+{
+ m_value = value;
+}
+
+uint16_t Ipv6OptionRouterAlertHeader::GetValue () const
+{
+ return m_value;
+}
+
+void Ipv6OptionRouterAlertHeader::Print (std::ostream &os) const
+{
+ os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << " value = " << (uint32_t)m_value << " )";
+}
+
+uint32_t Ipv6OptionRouterAlertHeader::GetSerializedSize () const
+{
+ return GetLength () + 2;
+}
+
+void Ipv6OptionRouterAlertHeader::Serialize (Buffer::Iterator start) const
+{
+ Buffer::Iterator i = start;
+
+ i.WriteU8 (GetType ());
+ i.WriteU8 (GetLength ());
+ i.WriteHtonU16 (m_value);
+}
+
+uint32_t Ipv6OptionRouterAlertHeader::Deserialize (Buffer::Iterator start)
+{
+ Buffer::Iterator i = start;
+
+ SetType (i.ReadU8 ());
+ SetLength (i.ReadU8 ());
+ m_value = i.ReadNtohU16 ();
+
+ return GetSerializedSize ();
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-option-header.h Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,385 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#ifndef IPV6_OPTION_HEADER_H
+#define IPV6_OPTION_HEADER_H
+
+#include <ostream>
+
+#include "ns3/header.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6OptionHeader
+ * \brief Header for IPv6 Option.
+ */
+class Ipv6OptionHeader : public Header
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6OptionHeader ();
+
+ /**
+ * \brief Set the type of the option.
+ * \param type the type of the option
+ */
+ void SetType (uint8_t type);
+
+ /**
+ * \brief Get the type of the optionr.
+ * \return the type of the option
+ */
+ uint8_t GetType () const;
+
+ /**
+ * \brief Set the option length.
+ * \param length the option length
+ */
+ void SetLength (uint8_t length);
+
+ /**
+ * \brief Get the option length.
+ * \return the option length
+ */
+ uint8_t GetLength () const;
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The type of the option.
+ */
+ uint8_t m_type;
+
+ /**
+ * \brief The option length.
+ */
+ uint8_t m_length;
+
+};
+
+/**
+ * \class Ipv6OptionPad1Header
+ * \brief Header of IPv6 Option Pad1
+ */
+class Ipv6OptionPad1Header : public Ipv6OptionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionPad1Header ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6OptionPad1Header ();
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+};
+
+/**
+ * \class Ipv6OptionPadnHeader
+ * \brief Header of IPv6 Option Padn
+ */
+class Ipv6OptionPadnHeader : public Ipv6OptionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionPadnHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6OptionPadnHeader ();
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+};
+
+/**
+ * \class Ipv6OptionJumbogramHeader
+ * \brief Header of IPv6 Option Jumbogram
+ */
+class Ipv6OptionJumbogramHeader : public Ipv6OptionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionJumbogramHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6OptionJumbogramHeader ();
+
+ /**
+ * \brief Set the data length.
+ * \param dataLength the data length
+ */
+ void SetDataLength (uint32_t dataLength);
+
+ /**
+ * \brief Get the data length.
+ * \return the data length
+ */
+ uint32_t GetDataLength () const;
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The data length.
+ */
+ uint32_t m_dataLength;
+};
+
+/**
+ * \class Ipv6OptionRouterAlertHeader
+ * \brief Header of IPv6 Option Router Alert
+ */
+class Ipv6OptionRouterAlertHeader : public Ipv6OptionHeader
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Get the instance type ID.
+ * \return instance type ID
+ */
+ virtual TypeId GetInstanceTypeId () const;
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionRouterAlertHeader ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6OptionRouterAlertHeader ();
+
+ /**
+ * \brief Set the field "value".
+ */
+ void SetValue (uint16_t value);
+
+ /**
+ * \brief Get the field "value".
+ * \return the field "value"
+ */
+ uint16_t GetValue () const;
+
+ /**
+ * \brief Print some informations about the packet.
+ * \param os output stream
+ * \return info about this packet
+ */
+ virtual void Print (std::ostream &os) const;
+
+ /**
+ * \brief Get the serialized size of the packet.
+ * \return size
+ */
+ virtual uint32_t GetSerializedSize () const;
+
+ /**
+ * \brief Serialize the packet.
+ * \param start Buffer iterator
+ */
+ virtual void Serialize (Buffer::Iterator start) const;
+
+ /**
+ * \brief Deserialize the packet.
+ * \param start Buffer iterator
+ * \return size of the packet
+ */
+ virtual uint32_t Deserialize (Buffer::Iterator start);
+
+ private:
+ /**
+ * \brief The value.
+ */
+ uint16_t m_value;
+};
+
+} // namespace ns3
+
+#endif /* IPV6_OPTION_HEADER_H */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-option.cc Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,242 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/uinteger.h"
+#include "ipv6-option.h"
+#include "ipv6-option-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6Option");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6Option);
+
+TypeId Ipv6Option::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6Option")
+ .SetParent<Object> ()
+ .AddAttribute ("OptionNumber", "The IPv6 option number.",
+ UintegerValue (0),
+ MakeUintegerAccessor (&Ipv6Option::GetOptionNumber),
+ MakeUintegerChecker<uint8_t> ())
+ ;
+ return tid;
+}
+
+Ipv6Option::~Ipv6Option ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6Option::SetNode (Ptr<Node> node)
+{
+ NS_LOG_FUNCTION (this << node);
+ m_node = node;
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionPad1);
+
+const uint8_t Ipv6OptionPad1::OPT_NUMBER = 0;
+
+TypeId Ipv6OptionPad1::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionPad1")
+ .SetParent<Ipv6Option> ()
+ .AddConstructor<Ipv6OptionPad1> ()
+ ;
+ return tid;
+}
+
+Ipv6OptionPad1::Ipv6OptionPad1 ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6OptionPad1::~Ipv6OptionPad1 ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6OptionPad1::GetOptionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return OPT_NUMBER;
+}
+
+uint8_t Ipv6OptionPad1::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ipv6OptionPad1Header pad1Header;
+ p->RemoveHeader (pad1Header);
+
+ isDropped = false;
+
+ return pad1Header.GetSerializedSize ();
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionPadn);
+
+const uint8_t Ipv6OptionPadn::OPT_NUMBER = 60;
+
+TypeId Ipv6OptionPadn::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionPadn")
+ .SetParent<Ipv6Option> ()
+ .AddConstructor<Ipv6OptionPadn> ()
+ ;
+ return tid;
+}
+
+Ipv6OptionPadn::Ipv6OptionPadn ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6OptionPadn::~Ipv6OptionPadn ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6OptionPadn::GetOptionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return OPT_NUMBER;
+}
+
+uint8_t Ipv6OptionPadn::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ipv6OptionPadnHeader padnHeader;
+ p->RemoveHeader (padnHeader);
+
+ isDropped = false;
+
+ return padnHeader.GetSerializedSize ();
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionJumbogram);
+
+const uint8_t Ipv6OptionJumbogram::OPT_NUMBER = 44;
+
+TypeId Ipv6OptionJumbogram::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionJumbogram")
+ .SetParent<Ipv6Option> ()
+ .AddConstructor<Ipv6OptionJumbogram> ()
+ ;
+ return tid;
+}
+
+Ipv6OptionJumbogram::Ipv6OptionJumbogram ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6OptionJumbogram::~Ipv6OptionJumbogram ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6OptionJumbogram::GetOptionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return OPT_NUMBER;
+}
+
+uint8_t Ipv6OptionJumbogram::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ipv6OptionJumbogramHeader jumbogramHeader;
+ p->RemoveHeader (jumbogramHeader);
+
+ isDropped = false;
+
+ return jumbogramHeader.GetSerializedSize ();
+}
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6OptionRouterAlert);
+
+const uint8_t Ipv6OptionRouterAlert::OPT_NUMBER = 43;
+
+TypeId Ipv6OptionRouterAlert::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::Ipv6OptionRouterAlert")
+ .SetParent<Ipv6Option> ()
+ .AddConstructor<Ipv6OptionRouterAlert> ()
+ ;
+ return tid;
+}
+
+Ipv6OptionRouterAlert::Ipv6OptionRouterAlert ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6OptionRouterAlert::~Ipv6OptionRouterAlert ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6OptionRouterAlert::GetOptionNumber () const
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ return OPT_NUMBER;
+}
+
+uint8_t Ipv6OptionRouterAlert::Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped)
+{
+ NS_LOG_FUNCTION (this << packet << offset << ipv6Header << ipv6Interface << isDropped);
+
+ Ptr<Packet> p = packet->Copy ();
+ p->RemoveAtStart (offset);
+
+ Ipv6OptionRouterAlertHeader routerAlertHeader;
+ p->RemoveHeader (routerAlertHeader);
+
+ isDropped = false;
+
+ return routerAlertHeader.GetSerializedSize ();
+}
+
+} /* namespace ns3 */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv6-option.h Thu Oct 15 15:11:27 2009 +0200
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007-2009 Strasbourg University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: David Gross <gdavid.devel@gmail.com>
+ */
+
+#ifndef IPV6_OPTION_H
+#define IPV6_OPTION_H
+
+#include <map>
+
+#include "ns3/object.h"
+#include "ns3/node.h"
+#include "ns3/ptr.h"
+#include "ipv6-interface.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/buffer.h"
+#include "ns3/packet.h"
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6Option
+ * \brief IPv6 Option base
+ * If you want to implement a new IPv6 option, all you have to do is
+ * implement a subclass of this class and add it to an Ipv6OptionDemux.
+ */
+class Ipv6Option : public Object
+{
+ public:
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Destructor.
+ */
+ virtual ~Ipv6Option ();
+
+ /**
+ * \brief Set the node.
+ * \param node the node to set
+ */
+ void SetNode (Ptr<Node> node);
+
+ /**
+ * \brief Get the option number.
+ * \return option number
+ */
+ virtual uint8_t GetOptionNumber () const = 0;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param isDropped if the packet must be dropped
+ * \return the processed size
+ */
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped) = 0;
+
+ private:
+ /**
+ * \brief The node.
+ */
+ Ptr<Node> m_node;
+};
+
+/**
+ * \class Ipv6OptionPad1
+ * \brief IPv6 Option Pad1
+ */
+class Ipv6OptionPad1 : public Ipv6Option
+{
+ public:
+ static const uint8_t OPT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionPad1 ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6OptionPad1 ();
+
+ /**
+ * \brief Get the option number.
+ * \return option number
+ */
+ virtual uint8_t GetOptionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param isDropped if the packet must be dropped
+ * \return the processed size
+ */
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+};
+
+/**
+ * \class Ipv6OptionPadn
+ * \brief IPv6 Option Padn
+ */
+class Ipv6OptionPadn : public Ipv6Option
+{
+ public:
+ static const uint8_t OPT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionPadn ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6OptionPadn ();
+
+ /**
+ * \brief Get the option number.
+ * \return option number
+ */
+ virtual uint8_t GetOptionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param isDropped if the packet must be dropped
+ * \return the processed size
+ */
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+};
+
+/**
+ * \class Ipv6OptionJumbogram
+ * \brief IPv6 Option Jumbogram
+ */
+class Ipv6OptionJumbogram : public Ipv6Option
+{
+ public:
+ static const uint8_t OPT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionJumbogram ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6OptionJumbogram ();
+
+ /**
+ * \brief Get the option number.
+ * \return option number
+ */
+ virtual uint8_t GetOptionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param isDropped if the packet must be dropped
+ * \return the processed size
+ */
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+
+ private:
+ /**
+ * \brief The length of the packet.
+ */
+ uint32_t m_length;
+};
+
+/**
+ * \class Ipv6OptionRouterAlert
+ * \brief IPv6 Option Router Alert
+ */
+class Ipv6OptionRouterAlert : public Ipv6Option
+{
+ public:
+ static const uint8_t OPT_NUMBER;
+
+ /**
+ * \brief Get the type identificator.
+ * \return type identificator
+ */
+ static TypeId GetTypeId ();
+
+ /**
+ * \brief Constructor.
+ */
+ Ipv6OptionRouterAlert ();
+
+ /**
+ * \brief Destructor.
+ */
+ ~Ipv6OptionRouterAlert ();
+
+ /**
+ * \brief Get the option number.
+ * \return option number
+ */
+ virtual uint8_t GetOptionNumber () const;
+
+ /**
+ * \brief Process method
+ * Called from Ipv6L3Protocol::Receive.
+ * \param packet the packet
+ * \param offset the offset of the extension to process
+ * \param ipv6Header the IPv6 header of packet received
+ * \param ipv6Interface the Ipv6Interface on which the packet arrived
+ * \param isDropped if the packet must be dropped
+ * \return the processed size
+ */
+ virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, Ptr<Ipv6Interface> ipv6Interface, bool& isDropped);
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_OPTION_H */
+
--- a/src/internet-stack/wscript Wed Oct 14 11:20:49 2009 -0700
+++ b/src/internet-stack/wscript Thu Oct 15 15:11:27 2009 +0200
@@ -99,8 +99,8 @@
'icmpv4.cc',
'icmpv4-l4-protocol.cc',
'loopback-net-device.cc',
+ 'ndisc-cache.cc',
'ipv6-interface.cc',
- 'ndisc-cache.cc',
'icmpv6-header.cc',
'ipv6-l3-protocol.cc',
'ipv6-end-point.cc',
@@ -109,6 +109,12 @@
'ipv6-raw-socket-factory-impl.cc',
'ipv6-raw-socket-impl.cc',
'ipv6-autoconfigured-prefix.cc',
+ 'ipv6-extension.cc',
+ 'ipv6-extension-header.cc',
+ 'ipv6-extension-demux.cc',
+ 'ipv6-option.cc',
+ 'ipv6-option-header.cc',
+ 'ipv6-option-demux.cc',
'icmpv6-l4-protocol.cc',
'ipv6-test.cc'
]