Add IPv6 extension files from old ns-3-ipv6 repository (not working yet).
authorSebastien Vincent <vincent@clarinet.u-strasbg.fr>
Thu, 15 Oct 2009 15:11:27 +0200
changeset 5782 f5299c974f1b
parent 5419 f54e261e92ed
child 5783 66c507d12317
Add IPv6 extension files from old ns-3-ipv6 repository (not working yet).
src/internet-stack/ipv6-extension-demux.cc
src/internet-stack/ipv6-extension-demux.h
src/internet-stack/ipv6-extension-header.cc
src/internet-stack/ipv6-extension-header.h
src/internet-stack/ipv6-extension.cc
src/internet-stack/ipv6-extension.h
src/internet-stack/ipv6-option-demux.cc
src/internet-stack/ipv6-option-demux.h
src/internet-stack/ipv6-option-header.cc
src/internet-stack/ipv6-option-header.h
src/internet-stack/ipv6-option.cc
src/internet-stack/ipv6-option.h
src/internet-stack/wscript
--- /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'
         ]