IPv6 extension support

View: New views
18 Messages — Rating Filter:   Alert me  

IPv6 extension support

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

I have found some time to integrate IPv6 extensions contributed last
year by David Gross during a placement and some improvement patch from
Fabian Mauchle.

I will release source by the end of the week. And I propose this feature
for a merge in ns-3.7.

Basically it support parsing IPv6 extensions and options. The most
useful stuff is fragmentation and routing type 0 (deprecated and
dangerous extension but we include it for some case studies). Other
extensions can be parsed (hop-by-hop, AH, ESP, ...) but for now there
are no special processing.

IPv6 extension support is the base for an future implementation of
Mobile IPv6. If I remember correctly someone (Fabian Mauchle ?) worked
on a MIPv6 implementation last year.

Best regards,
--
Sebastien


Re: IPv6 extension support

by Faker Moatamri :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sebastien Vincent wrote:
> Hi all,
>
> I have found some time to integrate IPv6 extensions contributed last
> year by David Gross during a placement and some improvement patch from
> Fabian Mauchle.
>
cool
> I will release source by the end of the week. And I propose this
> feature for a merge in ns-3.7.
>
Yes sure, please ask for a review as soon as your code is ready. Here
are guidelines (just in case you didn't hear about it) for code
submission: http://www.nsnam.org/code-submission.html.

> Basically it support parsing IPv6 extensions and options. The most
> useful stuff is fragmentation and routing type 0 (deprecated and
> dangerous extension but we include it for some case studies). Other
> extensions can be parsed (hop-by-hop, AH, ESP, ...) but for now there
> are no special processing.
> IPv6 extension support is the base for an future implementation of
> Mobile IPv6. If I remember correctly someone (Fabian Mauchle ?) worked
> on a MIPv6 implementation last year.
>
> Best regards,
> --
> Sebastien
>
Best regards
Faker Moatamri

Re: IPv6 extension support

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Here is the repository for IPv6 extension support:
http://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext/

It contains two new examples:
- fragmentation-ipv6, a node sends packets > MTU, packets are fragmented
in IPv6 stack;
- loose-routing-ipv6, a node sends special ICMPv6 which have IPv6
routing header type 0 (it choose the router path).

There are some stuff that could/have to be enhanced:
- In ipv6-static-routing.cc, class Ipv6LooseRoutingExtension send
directly the packets instead of passing up to Ipv6L3Protocol and it need
Ipv6StaticRouting object to have a lookup (StaticLookup) in routing
table (I don't need LocalDeliver/IpForward, ... callbacks). To do this I
copy code from Ipv6RoutingHelper to get Ipv6StaticRouting object from
Ipv6L3Protocol::GetRoutingProtocol. So we have the following choices:
  - include an helper class in stack (not sure it is good);
  - refactor to pass processed packets with routing header in IPv6 stack
(tag, ...);
  - add a virtual method in Ipv6RoutingProtocol that just look in
routing table for a destination (stuff like RouteInput() with no
callback) and returns a route.

- The IPv6 option processing, as suggested by Fabian Mauchle, it should
not have an Ipv6OptionDemux class and Ipv6Option process method because
of conceptual stuff. Maybe he can say more about it and provide a way to
do this.

As usual, any feedback is welcome.

Best regards,
--
Sebastien

Sebastien Vincent a écrit :

> Hi all,
>
> I have found some time to integrate IPv6 extensions contributed last
> year by David Gross during a placement and some improvement patch from
> Fabian Mauchle.
>
> I will release source by the end of the week. And I propose this
> feature for a merge in ns-3.7.
>
> Basically it support parsing IPv6 extensions and options. The most
> useful stuff is fragmentation and routing type 0 (deprecated and
> dangerous extension but we include it for some case studies). Other
> extensions can be parsed (hop-by-hop, AH, ESP, ...) but for now there
> are no special processing.
> IPv6 extension support is the base for an future implementation of
> Mobile IPv6. If I remember correctly someone (Fabian Mauchle ?) worked
> on a MIPv6 implementation last year.
>
> Best regards,
> --
> Sebastien
>
>


UDPv6

by Fabian Mauchle :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Sebastien, Hi all,

As we are heading on with merging more of Ipv6, I just wondered about UDPv6.
What is the current state of this, and will it be included in ns3.7?

Regards,

Fabian



Re: UDPv6

by Tom Henderson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fabian Mauchle wrote:
> Hi Sebastien, Hi all,
>
> As we are heading on with merging more of Ipv6, I just wondered about UDPv6.
> What is the current state of this, and will it be included in ns3.7?

Fabian, this is the most recent update that has been on the list, and
I'm not aware of any recent change:
http://mailman.isi.edu/pipermail/ns-developers/2009-July/006211.html

By the way, I have started a wiki page to track open issues with the
internet stack and routing (comments welcome), and linked this page from
  the ns-3.7 roadmap.  I will probably next try to look at the NSC
multiple interface problem and the code that Florian posted a while back.
http://www.nsnam.org/wiki/index.php/Internet-stack-maintenance

- Tom

Re: UDPv6

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Tom Henderson a écrit :

> Fabian Mauchle wrote:
>> Hi Sebastien, Hi all,
>>
>> As we are heading on with merging more of Ipv6, I just wondered about
>> UDPv6.
>> What is the current state of this, and will it be included in ns3.7?
>
> Fabian, this is the most recent update that has been on the list, and
> I'm not aware of any recent change:
> http://mailman.isi.edu/pipermail/ns-developers/2009-July/006211.html
>

I have not started anything on UDP/TCP refactoring and I'm affraid I
will not have time to work on it until december/january.
I prefer to take my little free time for merge IPv6 extension in ns-3.7
(available at https://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext).

Fabian has proposed to remove "IPv6 option demux" design from above
source tree. His repository is located at
http://sinv-56031.edu.hsr.ch/hg/ns-3-ipv6-ext. So feel free to review
these repositories and give feedback about the two solutions.

Best regards,
--
Sebastien


> By the way, I have started a wiki page to track open issues with the
> internet stack and routing (comments welcome), and linked this page
> from  the ns-3.7 roadmap.  I will probably next try to look at the NSC
> multiple interface problem and the code that Florian posted a while back.
> http://www.nsnam.org/wiki/index.php/Internet-stack-maintenance
>
> - Tom
>


Re: UDPv6

by Faker Moatamri :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sébastien Vincent wrote:

> Hi,
>
> Tom Henderson a écrit :
>> Fabian Mauchle wrote:
>>> Hi Sebastien, Hi all,
>>>
>>> As we are heading on with merging more of Ipv6, I just wondered
>>> about UDPv6.
>>> What is the current state of this, and will it be included in ns3.7?
>>
>> Fabian, this is the most recent update that has been on the list, and
>> I'm not aware of any recent change:
>> http://mailman.isi.edu/pipermail/ns-developers/2009-July/006211.html
>>
>
> I have not started anything on UDP/TCP refactoring and I'm affraid I
> will not have time to work on it until december/january.
> I prefer to take my little free time for merge IPv6 extension in
> ns-3.7 (available at https://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext).
>
I prepared a patch based on the above repository which is included in
the mail.
I also uploaded the code change in Rietveld so it is easier to review:
http://codereview.appspot.com/144048
I will be reviewing the code very soon. Tom, Craig, can you give a quick
review to the code?
Anyone else can review the code?

> Fabian has proposed to remove "IPv6 option demux" design from above
> source tree. His repository is located at
> http://sinv-56031.edu.hsr.ch/hg/ns-3-ipv6-ext. So feel free to review
> these repositories and give feedback about the two solutions.
Is there any reason why he did that? reviewing the first code is enough
right?
Best regards
Faker Moatamri


diff -wrbBPu ns-3-dev/examples/ipv6/fragmentation-ipv6.cc ns-3-ipv6-ext/examples/ipv6/fragmentation-ipv6.cc
--- ns-3-dev/examples/ipv6/fragmentation-ipv6.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/examples/ipv6/fragmentation-ipv6.cc 2009-10-29 10:36:21.540604000 +0100
@@ -0,0 +1,164 @@
+/* -*-  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@...>
+ *         Sebastien Vincent <vincent@...>
+ */
+
+// Network topology
+// //
+// //             n0   r    n1
+// //             |    _    |
+// //             ====|_|====
+// //                router
+// //
+// // - Tracing of queues and packet receptions to file "fragmentation-ipv6.tr"
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+#include "ns3/ipv6-routing-table-entry.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("FragmentationIpv6Example");
+
+/**
+ * \class StackHelper
+ * \brief Helper to set or get some IPv6 information about nodes.
+ */
+class StackHelper
+{
+  public:
+
+    /**
+     * \brief Add an address to a IPv6 node.
+     * \param n node
+     * \param interface interface index
+     * \param address IPv6 address to add
+     */
+    inline void AddAddress (Ptr<Node>& n, uint32_t interface, Ipv6Address address)
+    {
+      Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+      ipv6->AddAddress (interface, address);
+    }
+
+    /**
+     * \brief Print the routing table.
+     * \param n the node
+     */
+    inline void PrintRoutingTable (Ptr<Node>& n)
+    {
+      Ptr<Ipv6StaticRouting> routing = 0;
+      Ipv6StaticRoutingHelper routingHelper;
+      Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
+      uint32_t nbRoutes = 0;
+      Ipv6RoutingTableEntry route;
+
+      routing = routingHelper.GetStaticRouting (ipv6);
+
+      std::cout << "Routing table of " << n << " : " << std::endl;
+      std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" <<  "Prefix to use" << std::endl;
+
+      nbRoutes = routing->GetNRoutes ();
+      for (uint32_t i = 0 ; i < nbRoutes ; i++)
+      {
+        route = routing->GetRoute (i);
+        std::cout << route.GetDest () << "\t"
+          << route.GetGateway () << "\t"
+          << route.GetInterface () << "\t"
+          << route.GetPrefixToUse () << "\t"
+          << std::endl;
+      }
+    }
+};
+
+int main (int argc, char** argv)
+{
+#if 0
+  LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
+  LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
+  LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
+  LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
+  LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
+#endif
+
+ CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  StackHelper stackHelper;
+  
+ NS_LOG_INFO ("Create nodes.");
+ Ptr<Node> n0 = CreateObject<Node> ();
+ Ptr<Node> r = CreateObject<Node> ();
+ Ptr<Node> n1 = CreateObject<Node> ();
+
+ NodeContainer net1 (n0, r);
+ NodeContainer net2 (r, n1);
+ NodeContainer all (n0, r, n1);
+
+ NS_LOG_INFO ("Create IPv6 Internet Stack");
+  InternetStackHelper internetv6;
+  internetv6.Install (all);
+
+  NS_LOG_INFO ("Create channels.");
+ CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+ NetDeviceContainer d1 = csma.Install (net1);
+ NetDeviceContainer d2 = csma.Install (net2);
+
+ NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
+ Ipv6AddressHelper ipv6;
+ ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64);
+ Ipv6InterfaceContainer i1 = ipv6.Assign (d1);
+  i1.SetRouter (1, true);
+ ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64);
+ Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
+  i2.SetRouter (0, true);
+
+  stackHelper.PrintRoutingTable(n0);
+
+  /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via r */
+  uint32_t packetSize = 4096;
+  uint32_t maxPacketCount = 5;
+  Time interPacketInterval = Seconds (1.);
+  Ping6Helper ping6;
+
+  ping6.SetLocal (i1.GetAddress (0, 1));
+  ping6.SetRemote (i2.GetAddress (1, 1));
+
+  ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+  ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
+  ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
+  ApplicationContainer apps = ping6.Install (net1.Get (0));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (20.0));
+
+ std::ofstream ascii;
+  ascii.open ("fragmentation-ipv6.tr");
+  CsmaHelper::EnablePcapAll (std::string ("fragmentation-ipv6"), true);
+  CsmaHelper::EnableAsciiAll (ascii);
+
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
+
diff -wrbBPu ns-3-dev/examples/ipv6/icmpv6-redirect.cc ns-3-ipv6-ext/examples/ipv6/icmpv6-redirect.cc
--- ns-3-dev/examples/ipv6/icmpv6-redirect.cc 2009-10-23 16:01:56.558280000 +0200
+++ ns-3-ipv6-ext/examples/ipv6/icmpv6-redirect.cc 2009-10-29 10:36:21.542604000 +0100
@@ -15,7 +15,7 @@
  * 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 <david.gross@...>
+ * Author: David Gross <gdavid.devel@...>
  */
 
 // Network topology
diff -wrbBPu ns-3-dev/examples/ipv6/loose-routing-ipv6.cc ns-3-ipv6-ext/examples/ipv6/loose-routing-ipv6.cc
--- ns-3-dev/examples/ipv6/loose-routing-ipv6.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/examples/ipv6/loose-routing-ipv6.cc 2009-10-29 10:36:21.544604000 +0100
@@ -0,0 +1,171 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 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@...>
+ */
+
+// Network topology
+// //
+// //
+// //                               +------------+
+// //  +------------+           |---|  Router 1  |---|
+// //  |   Host 0   |--|        |   [------------]   |
+// //  [------------]  |        |                    |
+// //                  |  +------------+             |
+// //                  +--|            |       +------------+
+// //                     |  Router 0  |       |  Router 2  |
+// //                  +--|            |       [------------]
+// //                  |  [------------]             |
+// //  +------------+  |        |                    |
+// //  |   Host 1   |--|        |   +------------+   |
+// //  [------------]           |---|  Router 3  |---|
+// //                               [------------]  
+// //                                    
+// //
+// // - Tracing of queues and packet receptions to file "loose-routing-ipv6.tr"
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/ipv6-header.h"
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("LooseRoutingIpv6Example");
+
+int main (int argc, char **argv)
+{
+#if 0
+  LogComponentEnable("Ipv6ExtensionLooseRouting", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv6Extension", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv6L3Protocol", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv6StaticRouting", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv6Interface", LOG_LEVEL_ALL);
+  LogComponentEnable("Ipv6Interface", LOG_LEVEL_ALL);
+ LogComponentEnable("NdiscCache", LOG_LEVEL_ALL);
+#endif
+
+ CommandLine cmd;
+  cmd.Parse (argc, argv);
+  
+ NS_LOG_INFO ("Create nodes.");
+ Ptr<Node> h0 = CreateObject<Node> ();
+ Ptr<Node> h1 = CreateObject<Node> ();
+ Ptr<Node> r0 = CreateObject<Node> ();
+ Ptr<Node> r1 = CreateObject<Node> ();
+ Ptr<Node> r2 = CreateObject<Node> ();
+ Ptr<Node> r3 = CreateObject<Node> ();
+
+ NodeContainer net1 (h0, r0);
+ NodeContainer net2 (h1, r0);
+ NodeContainer net3 (r0, r1);
+ NodeContainer net4 (r1, r2);
+ NodeContainer net5 (r2, r3);
+ NodeContainer net6 (r3, r0);
+ NodeContainer all;
+ all.Add (h0);
+ all.Add (h1);
+ all.Add (r0);
+ all.Add (r1);
+ all.Add (r2);
+ all.Add (r3);
+
+ NS_LOG_INFO ("Create IPv6 Internet Stack");
+  InternetStackHelper internetv6;
+  internetv6.Install (all);
+
+  NS_LOG_INFO ("Create channels.");
+ CsmaHelper csma;
+ csma.SetDeviceAttribute ("Mtu", UintegerValue(1500));
+  csma.SetChannelAttribute ("DataRate", DataRateValue(5000000));
+  csma.SetChannelAttribute ("Delay", TimeValue(MilliSeconds (2)));
+ NetDeviceContainer d1 = csma.Install (net1);
+ NetDeviceContainer d2 = csma.Install (net2);
+ NetDeviceContainer d3 = csma.Install (net3);
+ NetDeviceContainer d4 = csma.Install (net4);
+ NetDeviceContainer d5 = csma.Install (net5);
+ NetDeviceContainer d6 = csma.Install (net6);
+
+ NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
+ Ipv6AddressHelper ipv6;
+
+ ipv6.NewNetwork (Ipv6Address ("2001:1::"), 64);
+ Ipv6InterfaceContainer i1 = ipv6.Assign (d1);
+ i1.SetRouter (1, true);
+
+ ipv6.NewNetwork (Ipv6Address ("2001:2::"), 64);
+ Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
+ i2.SetRouter (1, true);
+
+ ipv6.NewNetwork (Ipv6Address ("2001:3::"), 64);
+ Ipv6InterfaceContainer i3 = ipv6.Assign (d3);
+ i3.SetRouter (0, true);
+ i3.SetRouter (1, true);
+
+ ipv6.NewNetwork (Ipv6Address ("2001:4::"), 64);
+ Ipv6InterfaceContainer i4 = ipv6.Assign (d4);
+ i4.SetRouter (0, true);
+ i4.SetRouter (1, true);
+
+ ipv6.NewNetwork (Ipv6Address ("2001:5::"), 64);
+ Ipv6InterfaceContainer i5 = ipv6.Assign (d5);
+ i5.SetRouter (0, true);
+ i5.SetRouter (1, true);
+
+ ipv6.NewNetwork (Ipv6Address ("2001:6::"), 64);
+ Ipv6InterfaceContainer i6 = ipv6.Assign (d6);
+ i6.SetRouter (0, true);
+ i6.SetRouter (1, true);
+  
+  NS_LOG_INFO ("Create Applications.");
+
+ /**
+ * ICMPv6 Echo from h0 to h1 port 7
+ */
+  uint32_t packetSize = 1024;
+  uint32_t maxPacketCount = 1;
+  Time interPacketInterval = Seconds (1.);
+  
+ std::vector<Ipv6Address> routersAddress;
+ routersAddress.push_back (i3.GetAddress (1, 1));
+ routersAddress.push_back (i4.GetAddress (1, 1));
+ routersAddress.push_back (i5.GetAddress (1, 1));
+ routersAddress.push_back (i6.GetAddress (1, 1));
+ routersAddress.push_back (i2.GetAddress (0, 1));
+
+ Ping6Helper client;
+  /* remote address is first routers in RH0 => source routing */
+  client.SetRemote (i1.GetAddress (1, 1));
+  client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+  client.SetAttribute ("Interval", TimeValue(interPacketInterval));
+  client.SetAttribute ("PacketSize", UintegerValue (packetSize));
+ client.SetRoutersAddress (routersAddress);
+  ApplicationContainer apps = client.Install (h0);
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  std::ofstream ascii;
+  ascii.open ("loose-routing-ipv6.tr");
+  CsmaHelper::EnablePcapAll ("loose-routing-ipv6", true);
+  CsmaHelper::EnableAsciiAll (ascii);
+
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
+
diff -wrbBPu ns-3-dev/examples/ipv6/wscript ns-3-ipv6-ext/examples/ipv6/wscript
--- ns-3-dev/examples/ipv6/wscript 2009-10-23 16:01:56.569282000 +0200
+++ ns-3-ipv6-ext/examples/ipv6/wscript 2009-10-29 10:36:21.556604000 +0100
@@ -15,3 +15,10 @@
 
     obj = bld.create_ns3_program('test-ipv6', ['point-to-point', 'internet-stack'])
     obj.source = 'test-ipv6.cc'
+    
+    obj = bld.create_ns3_program('fragmentation-ipv6', ['csma', 'internet-stack'])
+    obj.source = 'fragmentation-ipv6.cc'
+
+    obj = bld.create_ns3_program('loose-routing-ipv6', ['csma', 'internet-stack'])
+    obj.source = 'loose-routing-ipv6.cc'
+
diff -wrbBPu ns-3-dev/src/applications/ping6/ping6.cc ns-3-ipv6-ext/src/applications/ping6/ping6.cc
--- ns-3-dev/src/applications/ping6/ping6.cc 2009-10-23 16:01:57.155217000 +0200
+++ ns-3-ipv6-ext/src/applications/ping6/ping6.cc 2009-10-29 10:36:21.868604000 +0100
@@ -31,6 +31,7 @@
 #include "ns3/icmpv6-header.h"
 #include "ns3/ipv6-raw-socket-factory.h"
 #include "ns3/ipv6-header.h"
+#include "ns3/ipv6-extension-header.h"
 
 #include "ping6.h"
 
@@ -109,7 +110,7 @@
 
     m_socket->Bind (Inet6SocketAddress (m_localAddress, 0));
     m_socket->Connect (Inet6SocketAddress (m_peerAddress, 0));
-    m_socket->SetAttribute ("Protocol", UintegerValue (58)); /* ICMPv6 */
+    m_socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6));
     m_socket->SetRecvCallback (MakeCallback (&Ping6::HandleRead, this));
   }
 
@@ -151,12 +152,17 @@
   m_sendEvent = Simulator::Schedule (dt, &Ping6::Send, this);
 }
 
+void Ping6::SetRouters (std::vector<Ipv6Address> routersAddress)
+{
+  m_routersAddress = routersAddress;
+}
+
 void Ping6::Send ()
 {
   NS_LOG_FUNCTION_NOARGS ();
   NS_ASSERT (m_sendEvent.IsExpired ());
   Ptr<Packet> p = 0;
-  uint8_t data[4];
+  uint8_t data[m_size];
   Ipv6Address src;
   Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
 
@@ -172,12 +178,14 @@
     src = m_localAddress;
   }
 
+  NS_ASSERT_MSG (m_size >= 4, "ICMPv6 echo request payload size must be >= 4");
   data[0] = 0xDE;
   data[1] = 0xAD;
   data[2] = 0xBE;
   data[3] = 0xEF;
 
-  p = Create<Packet>(data, sizeof (data));
+  p = Create<Packet> (data, 4);
+  p->AddAtEnd (Create<Packet> (m_size - 4));
   Icmpv6Echo req (1);
 
   req.SetId (0xBEEF);
@@ -190,6 +198,20 @@
 
   p->AddHeader (req);
   m_socket->Bind (Inet6SocketAddress (src, 0));
+
+  /* use routing type 0 */
+  if (m_routersAddress.size ())
+  {
+    Ipv6ExtensionLooseRoutingHeader routingHeader;
+    routingHeader.SetNextHeader (Ipv6Header::IPV6_ICMPV6);
+    routingHeader.SetLength (m_routersAddress.size () * 16 + 8);
+    routingHeader.SetTypeRouting (0);
+    routingHeader.SetSegmentsLeft (m_routersAddress.size ());
+    routingHeader.SetRoutersAddress (m_routersAddress);
+    p->AddHeader (routingHeader);
+    m_socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_EXT_ROUTING));
+  }
+
   m_socket->Send (p, 0);
   ++m_sent;
 
diff -wrbBPu ns-3-dev/src/applications/ping6/ping6.h ns-3-ipv6-ext/src/applications/ping6/ping6.h
--- ns-3-dev/src/applications/ping6/ping6.h 2009-10-23 16:01:57.158207000 +0200
+++ ns-3-ipv6-ext/src/applications/ping6/ping6.h 2009-10-29 10:36:21.870604000 +0100
@@ -81,6 +81,12 @@
      */
     void SetIfIndex (uint32_t ifIndex);
 
+    /**
+     * \brief Set routers for routing type 0 (loose routing).
+     * \param routers routers
+     */
+    void SetRouters(std::vector<Ipv6Address> routersAddress);
+
   protected:
     /**
      * \brief Dispose this object;
@@ -169,6 +175,11 @@
      * \brief Out interface (i.e. for link-local communication).
      */
     uint32_t m_ifIndex;
+
+    /**
+     * \brief Routers addresses for routing type 0.
+     */
+    std::vector<Ipv6Address> m_routersAddress;
 };
 
 } /* namespace ns3 */
diff -wrbBPu ns-3-dev/src/applications/radvd/radvd.cc ns-3-ipv6-ext/src/applications/radvd/radvd.cc
--- ns-3-dev/src/applications/radvd/radvd.cc 2009-10-23 16:01:57.174204000 +0200
+++ ns-3-ipv6-ext/src/applications/radvd/radvd.cc 2009-10-29 10:36:21.890604000 +0100
@@ -87,7 +87,7 @@
 
 /*    m_socket->Bind (Inet6SocketAddress (m_localAddress, 0)); */
 /*    m_socket->Connect (Inet6SocketAddress (Ipv6Address::GetAllNodesMulticast (), 0)); */
-    m_socket->SetAttribute ("Protocol", UintegerValue (58)); /* ICMPv6 */
+    m_socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6));
     m_socket->SetRecvCallback (MakeCallback (&Radvd::HandleRead, this));
   }
 
diff -wrbBPu ns-3-dev/src/helper/internet-stack-helper.cc ns-3-ipv6-ext/src/helper/internet-stack-helper.cc
--- ns-3-dev/src/helper/internet-stack-helper.cc 2009-10-23 16:01:58.516133000 +0200
+++ ns-3-ipv6-ext/src/helper/internet-stack-helper.cc 2009-10-29 10:36:23.152528000 +0100
@@ -360,6 +360,10 @@
       Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
       Ptr<Ipv6RoutingProtocol> ipv6Routing = m_routingv6->Create (node);
       ipv6->SetRoutingProtocol (ipv6Routing);
+
+      /* register IPv6 extensions and options */
+      ipv6->RegisterExtensions ();
+      ipv6->RegisterOptions ();
     }
 }
 
diff -wrbBPu ns-3-dev/src/helper/ping6-helper.cc ns-3-ipv6-ext/src/helper/ping6-helper.cc
--- ns-3-dev/src/helper/ping6-helper.cc 2009-10-23 16:01:58.659140000 +0200
+++ ns-3-ipv6-ext/src/helper/ping6-helper.cc 2009-10-29 10:36:23.255531000 +0100
@@ -57,6 +57,7 @@
     client->SetLocal (m_localIp);
     client->SetRemote (m_remoteIp);
     client->SetIfIndex (m_ifIndex);
+    client->SetRouters (m_routers);
     node->AddApplication (client);
     apps.Add (client);
   }
@@ -68,5 +69,10 @@
   m_ifIndex = ifIndex;
 }
 
+void Ping6Helper::SetRoutersAddress (std::vector<Ipv6Address> routers)
+{
+  m_routers = routers;
+}
+
 } /* namespace ns3 */
 
diff -wrbBPu ns-3-dev/src/helper/ping6-helper.h ns-3-ipv6-ext/src/helper/ping6-helper.h
--- ns-3-dev/src/helper/ping6-helper.h 2009-10-23 16:01:58.661132000 +0200
+++ ns-3-ipv6-ext/src/helper/ping6-helper.h 2009-10-29 10:36:23.258528000 +0100
@@ -77,6 +77,13 @@
      */
     void SetIfIndex (uint32_t ifIndex);
 
+
+    /**
+     * \brief Set routers addresses for routing type 0.
+     * \param routers routers addresses
+     */
+    void SetRoutersAddress(std::vector<Ipv6Address> routers);
+    
   private:
     /**
      * \brief An object factory.
@@ -97,6 +104,11 @@
      * \brief Out interface index.                      
      */
     uint32_t m_ifIndex;
+
+    /**
+     * \brief Routers addresses.
+     */
+    std::vector<Ipv6Address> m_routers;
 };
 
 } /* namespace ns3 */
diff -wrbBPu ns-3-dev/src/internet-stack/icmpv6-l4-protocol.cc ns-3-ipv6-ext/src/internet-stack/icmpv6-l4-protocol.cc
--- ns-3-dev/src/internet-stack/icmpv6-l4-protocol.cc 2009-10-23 16:01:58.740129000 +0200
+++ ns-3-ipv6-ext/src/internet-stack/icmpv6-l4-protocol.cc 2009-10-29 10:36:23.360454000 +0100
@@ -228,10 +228,15 @@
 {
   NS_LOG_FUNCTION (this << packet << src << dst << interface);
   Icmpv6Echo request;
+  uint8_t buf[packet->GetSize ()];
+
   packet->RemoveHeader (request);
+  /* XXX IPv6 extension: obtain a fresh copy of data otherwise it crash... */
+  packet->CopyData (buf, packet->GetSize ());
+  Ptr<Packet> p = Create<Packet> (buf, packet->GetSize ());
 
   /* if we send message from ff02::* (link-local multicast), we use our link-local address */
-  SendEchoReply (dst.IsMulticast () ? interface->GetLinkLocalAddress ().GetAddress () : dst, src, request.GetId (), request.GetSeq (), packet);
+  SendEchoReply (dst.IsMulticast () ? interface->GetLinkLocalAddress ().GetAddress () : dst, src, request.GetId (), request.GetSeq (), p);
 }
 
 void Icmpv6L4Protocol::HandleRA (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-extension.cc ns-3-ipv6-ext/src/internet-stack/ipv6-extension.cc
--- ns-3-dev/src/internet-stack/ipv6-extension.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-extension.cc 2009-10-29 10:36:23.436482000 +0100
@@ -0,0 +1,1084 @@
+/*  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@...>
+ */
+
+#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/ipv6-static-routing.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/ipv6-route.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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << 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, dst, 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, dst, 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, 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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << 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, dst, 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, dst, 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, 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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << 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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << 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, dst, ipv6Header.GetSourceAddress (), Icmpv6Header::ICMPV6_MALFORMED_HEADER, offset + 1); */
+      m_dropTrace (packet);
+      isDropped = true;
+    }
+
+    return routingLength;
+  }
+
+  return ipv6ExtensionRouting->Process (packet, offset, ipv6Header, dst, (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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << 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, dst, 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, dst, 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, dst, srcAddress, Icmpv6Header::ICMPV6_HOPLIMIT); */
+    m_dropTrace (packet);
+    isDropped = true;
+    return routingHeader.GetSerializedSize ();
+  }
+
+  routingHeader.SetLength (88);
+  ipv6header.SetHopLimit (hopLimit - 1);
+  p->AddHeader (routingHeader);
+
+  /* short-circuiting routing stuff */
+  
+  /* XXX taken from src/helper/ipv6-static-rouging.cc
+   *
+   * either include (and use) helper (Ipv6StaticRoutingHelper) or
+   * add a method in Ipv6RoutingProtocol to lookup in routing table
+   * without callback to Ipv6L3Protocol::LocalDeliver/IpForward/IpMulticastForward
+   */
+  Ptr<Ipv6L3Protocol> ipv6 = GetNode ()->GetObject<Ipv6L3Protocol> ();
+  Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
+  Ptr<Ipv6StaticRouting> staticRouting = 0;
+
+  NS_ASSERT_MSG (ipv6rp, "No routing protocol associated with Ipv6");
+  if (DynamicCast<Ipv6StaticRouting> (ipv6rp))
+  {
+    staticRouting = DynamicCast<Ipv6StaticRouting> (ipv6rp);
+  }
+  else if (DynamicCast<Ipv6ListRouting> (ipv6rp))
+  {
+    Ptr<Ipv6ListRouting> lrp = DynamicCast<Ipv6ListRouting> (ipv6rp);
+    int16_t priority;
+    for (uint32_t i = 0; i < lrp->GetNRoutingProtocols ();  i++)
+    {
+      NS_LOG_LOGIC ("Searching for static routing in list");
+      Ptr<Ipv6RoutingProtocol> temp = lrp->GetRoutingProtocol (i, priority);
+      if (DynamicCast<Ipv6StaticRouting> (temp))
+      {
+        NS_LOG_LOGIC ("Found static routing in list");
+        staticRouting = DynamicCast<Ipv6StaticRouting> (temp);
+        break;
+      }
+    }
+  }
+
+  NS_ASSERT (staticRouting);
+
+  Ptr<Ipv6Route> rtentry = staticRouting->LookupStatic (nextAddress, 0);
+
+  if (rtentry)
+  {
+    /* we know a route exists so send packet now */
+    ipv6->SendRealOut (rtentry, p, ipv6header);
+  }
+  else
+  {
+    NS_LOG_INFO("No route for next router");
+  }
+
+  /* as we directly send packet, mark it as dropped */
+  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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << 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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << dst << nextHeader << isDropped);
+
+  /* TODO */
+
+  return true;
+}
+
+} /* namespace ns3 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-extension-demux.cc ns-3-ipv6-ext/src/internet-stack/ipv6-extension-demux.cc
--- ns-3-dev/src/internet-stack/ipv6-extension-demux.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-extension-demux.cc 2009-10-29 10:36:23.419452000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-extension-demux.h ns-3-ipv6-ext/src/internet-stack/ipv6-extension-demux.h
--- ns-3-dev/src/internet-stack/ipv6-extension-demux.h 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-extension-demux.h 2009-10-29 10:36:23.421451000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-extension.h ns-3-ipv6-ext/src/internet-stack/ipv6-extension.h
--- ns-3-dev/src/internet-stack/ipv6-extension.h 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-extension.h 2009-10-29 10:36:23.439455000 +0100
@@ -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@...>
+ */
+
+#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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, 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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, 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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, 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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, 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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, 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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, 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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, 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 dst destination address of the packet received (i.e. us)
+     * \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, Ipv6Address dst, uint8_t *nextHeader, bool& isDropped);
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_EXTENSION_H */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-extension-header.cc ns-3-ipv6-ext/src/internet-stack/ipv6-extension-header.cc
--- ns-3-dev/src/internet-stack/ipv6-extension-header.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-extension-header.cc 2009-10-29 10:36:23.425454000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-extension-header.h ns-3-ipv6-ext/src/internet-stack/ipv6-extension-header.h
--- ns-3-dev/src/internet-stack/ipv6-extension-header.h 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-extension-header.h 2009-10-29 10:36:23.430463000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-l3-protocol.cc ns-3-ipv6-ext/src/internet-stack/ipv6-l3-protocol.cc
--- ns-3-dev/src/internet-stack/ipv6-l3-protocol.cc 2009-10-23 16:01:58.809102000 +0200
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-l3-protocol.cc 2009-10-29 10:36:23.452453000 +0100
@@ -34,6 +34,11 @@
 #include "ipv6-interface.h"
 #include "ipv6-raw-socket-impl.h"
 #include "ipv6-autoconfigured-prefix.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 "icmpv6-l4-protocol.h"
 #include "ndisc-cache.h"
 
@@ -692,6 +696,26 @@
     socket->ForwardUp (packet, hdr, device);
   }
 
+  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
+  Ptr<Ipv6Extension> ipv6Extension = 0;
+  uint8_t nextHeader = hdr.GetNextHeader ();
+  bool isDropped = false;
+
+  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+  {
+    ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
+
+    if (ipv6Extension)
+    {
+      ipv6Extension->Process (packet, 0, hdr, hdr.GetDestinationAddress (), (uint8_t *)0, isDropped);
+    }
+
+    if (isDropped)
+    {
+      return;
+    }
+  }
+
   m_routingProtocol->RouteInput (packet, hdr, device,
     MakeCallback (&Ipv6L3Protocol::IpForward, this),
     MakeCallback (&Ipv6L3Protocol::IpMulticastForward, this),
@@ -717,16 +741,51 @@
   Ptr<Ipv6Interface> outInterface = GetInterface (interface);
   NS_LOG_LOGIC ("Send via NetDevice ifIndex " << dev->GetIfIndex () << " Ipv6InterfaceIndex " << interface);
 
+  // Check packet size
+  std::list<Ptr<Packet> > fragments;
+
+  if (packet->GetSize () > (size_t)(dev->GetMtu () + 40)) /* 40 => size of IPv6 header */
+  {
+    // Router => drop
+    if (m_ipForward)
+    {
+      return;
+    }
+
+    Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux> ();
+
+    packet->AddHeader (ipHeader);
+
+    // To get specific method GetFragments from Ipv6ExtensionFragmentation
+    Ipv6ExtensionFragment *ipv6Fragment = dynamic_cast<Ipv6ExtensionFragment *>(PeekPointer (ipv6ExtensionDemux->GetExtension (Ipv6Header::IPV6_EXT_FRAGMENTATION)));
+    ipv6Fragment->GetFragments (packet, outInterface->GetDevice ()->GetMtu (), fragments);
+  }
+
   if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ()))
   {
     if (outInterface->IsUp ())
     {
       NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ());
+
+      if (fragments.size () != 0)
+      {
+        std::ostringstream oss;
+
+        /* IPv6 header is already added in fragments */
+        for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
+        {
+          m_txTrace (*it, interface);
+          outInterface->Send (*it, route->GetGateway ());
+        }
+      }
+      else
+      {
+        /* NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ()); */
       packet->AddHeader (ipHeader);
-      NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ());
       m_txTrace (packet, interface);
       outInterface->Send (packet, route->GetGateway ());
     }
+    }
     else
     {
       NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ());
@@ -738,11 +797,26 @@
     if (outInterface->IsUp ())
     {
        NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ());
+
+      if (fragments.size () != 0)
+      {
+        std::ostringstream oss;
+        
+        /* IPv6 header is already added in fragments */
+        for (std::list<Ptr<Packet> >::const_iterator it = fragments.begin (); it != fragments.end (); it++)
+        {
+          m_txTrace (*it, interface);
+          outInterface->Send (*it, ipHeader.GetDestinationAddress ());
+        }
+      }
+      else
+      {
+        /* NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ()); */
        packet->AddHeader (ipHeader);
-       NS_ASSERT (packet->GetSize () <= outInterface->GetDevice ()->GetMtu ());
        m_txTrace (packet, interface);
        outInterface->Send (packet, ipHeader.GetDestinationAddress ());
     }
+    }
     else
     {
       NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestinationAddress ());
@@ -855,8 +929,89 @@
 {
   NS_LOG_FUNCTION (this << packet << ip << iif);
   Ptr<Packet> p = packet->Copy ();
-  Ptr<Ipv6L4Protocol> protocol = GetProtocol (ip.GetNextHeader ());
+  Ptr<Ipv6L4Protocol> protocol = 0;
+/*GetProtocol (ip.GetNextHeader ());*/
+
+  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = m_node->GetObject<Ipv6ExtensionDemux>();
+  Ptr<Ipv6Extension> ipv6Extension = 0;
+
+  Ipv6Address src = ip.GetSourceAddress ();
+  Ipv6Address dst = ip.GetDestinationAddress ();
+  uint8_t nextHeader = ip.GetNextHeader ();
+  uint8_t nextHeaderPosition = 0;
+  bool isDropped = false;
+
+  if (nextHeader == Ipv6Header::IPV6_EXT_HOP_BY_HOP)
+  {
+    const uint8_t *buff = p->PeekData ();
+
+    nextHeader = *buff;
+    nextHeaderPosition = *(buff + 1);
+  }
+
+  do {
+    ipv6Extension = ipv6ExtensionDemux->GetExtension (nextHeader);
 
+    if (ipv6Extension)
+    {
+      nextHeaderPosition += ipv6Extension->Process (p, nextHeaderPosition, ip, dst, &nextHeader, isDropped);
+
+      if (isDropped)
+      {
+        return;
+      }
+    }
+    else
+    {
+      protocol = GetProtocol (nextHeader);
+
+      if (!protocol)
+      {
+        NS_LOG_LOGIC ("Unknown Next Header. Drop!");
+
+        if (nextHeaderPosition == 0)
+        {
+          /* TODO */
+          /* GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, src, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40); */
+        }
+        else
+        {
+          /* TODO */
+          /* GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, src, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, ip.GetSerializedSize () + nextHeaderPosition); */
+        }
+        m_dropTrace (ip, p, DROP_UNKNOWN_PROTOCOL, iif);
+        break;
+      }
+      else
+      {
+        p->RemoveAtStart (nextHeaderPosition);
+        /* protocol->Receive (p, src, dst, incomingInterface); */
+        
+        /* L4 protocol */
+        Ptr<Packet> copy = p->Copy ();
+        enum Ipv6L4Protocol::RxStatus_e status = protocol->Receive (p, ip.GetSourceAddress (), ip.GetDestinationAddress (), GetInterface (iif));
+
+        switch (status)
+        {
+        case Ipv6L4Protocol::RX_OK:
+          break;
+        case Ipv6L4Protocol::RX_CSUM_FAILED:
+          break;
+        case Ipv6L4Protocol::RX_ENDPOINT_UNREACH:
+          if (ip.GetDestinationAddress ().IsMulticast ())
+          {
+            /* do not rely on multicast address */
+            break;
+          }
+
+          copy->AddHeader (ip);
+          GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
+        }
+      }
+    }
+  } while (ipv6Extension);
+
+#if 0
   if (protocol)
   {
     Ptr<Packet> copy = p->Copy ();
@@ -879,6 +1034,7 @@
       GetIcmpv6 ()->SendErrorDestinationUnreachable (copy, ip.GetSourceAddress (), Icmpv6Header::ICMPV6_PORT_UNREACHABLE);
     }
   }
+#endif
 }
 
 void Ipv6L3Protocol::RouteInputError (Ptr<const Packet> p, const Ipv6Header& ipHeader, Socket::SocketErrno sockErrno)
@@ -901,5 +1057,60 @@
   return hdr;
 }
 
+void Ipv6L3Protocol::RegisterExtensions ()
+{
+  Ptr<Ipv6ExtensionDemux> ipv6ExtensionDemux = CreateObject<Ipv6ExtensionDemux> ();
+  ipv6ExtensionDemux->SetNode (m_node);
+
+  Ptr<Ipv6ExtensionHopByHop> hopbyhopExtension = CreateObject<Ipv6ExtensionHopByHop> ();
+  hopbyhopExtension->SetNode (m_node);
+  Ptr<Ipv6ExtensionDestination> destinationExtension = CreateObject<Ipv6ExtensionDestination> ();
+  destinationExtension->SetNode (m_node);
+  Ptr<Ipv6ExtensionFragment> fragmentExtension = CreateObject<Ipv6ExtensionFragment> ();
+  fragmentExtension->SetNode (m_node);
+  Ptr<Ipv6ExtensionRouting> routingExtension = CreateObject<Ipv6ExtensionRouting> ();
+  routingExtension->SetNode (m_node);
+  // Ptr<Ipv6ExtensionESP> espExtension = CreateObject<Ipv6ExtensionESP> ();
+  // Ptr<Ipv6ExtensionAH> ahExtension = CreateObject<Ipv6ExtensionAH> ();
+
+  ipv6ExtensionDemux->Insert (hopbyhopExtension);
+  ipv6ExtensionDemux->Insert (destinationExtension);
+  ipv6ExtensionDemux->Insert (fragmentExtension);
+  ipv6ExtensionDemux->Insert (routingExtension);
+  // ipv6ExtensionDemux->Insert (espExtension);
+  // ipv6ExtensionDemux->Insert (ahExtension);
+
+  Ptr<Ipv6ExtensionRoutingDemux> routingExtensionDemux = CreateObject<Ipv6ExtensionRoutingDemux> ();
+  routingExtensionDemux->SetNode (m_node);
+  Ptr<Ipv6ExtensionLooseRouting> looseRoutingExtension = CreateObject<Ipv6ExtensionLooseRouting> ();
+  looseRoutingExtension->SetNode (m_node);
+  routingExtensionDemux->Insert (looseRoutingExtension);
+
+  m_node->AggregateObject (routingExtensionDemux);
+  m_node->AggregateObject (ipv6ExtensionDemux);
+}
+
+void Ipv6L3Protocol::RegisterOptions ()
+{
+  Ptr<Ipv6OptionDemux> ipv6OptionDemux = CreateObject<Ipv6OptionDemux> ();
+  ipv6OptionDemux->SetNode (m_node);
+
+  Ptr<Ipv6OptionPad1> pad1Option = CreateObject<Ipv6OptionPad1> ();
+  pad1Option->SetNode (m_node);
+  Ptr<Ipv6OptionPadn> padnOption = CreateObject<Ipv6OptionPadn> ();
+  padnOption->SetNode (m_node);
+  Ptr<Ipv6OptionJumbogram> jumbogramOption = CreateObject<Ipv6OptionJumbogram> ();
+  jumbogramOption->SetNode (m_node);
+  Ptr<Ipv6OptionRouterAlert> routerAlertOption = CreateObject<Ipv6OptionRouterAlert> ();
+  routerAlertOption->SetNode (m_node);
+
+  ipv6OptionDemux->Insert (pad1Option);
+  ipv6OptionDemux->Insert (padnOption);
+  ipv6OptionDemux->Insert (jumbogramOption);
+  ipv6OptionDemux->Insert (routerAlertOption);
+
+  m_node->AggregateObject (ipv6OptionDemux);
+}
+
 } /* namespace ns3 */
 
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-l3-protocol.h ns-3-ipv6-ext/src/internet-stack/ipv6-l3-protocol.h
--- ns-3-dev/src/internet-stack/ipv6-l3-protocol.h 2009-10-23 16:01:58.812100000 +0200
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-l3-protocol.h 2009-10-29 10:36:23.457453000 +0100
@@ -79,6 +79,7 @@
         DROP_NO_ROUTE, /**< No route to host */
         DROP_INTERFACE_DOWN, /**< Interface is down so can not send packet */
         DROP_ROUTE_ERROR, /**< Route error */
+        DROP_UNKNOWN_PROTOCOL, /**< Unkown L4 protocol */
       };
     
     /**
@@ -329,6 +330,16 @@
      */
     void RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Address network, Ipv6Prefix mask, Ipv6Address defaultRouter);
 
+    /**
+     * \brief Register the IPv6 Extensions.
+     */
+    virtual void RegisterExtensions ();
+
+    /**
+     * \brief Register the IPv6 Options.
+     */
+    virtual void RegisterOptions ();
+
   protected:
     /**
      * \brief Dispose object.
@@ -345,6 +356,7 @@
   private:
     /* for unit-tests */
     friend class Ipv6L3ProtocolTestCase;
+    friend class Ipv6ExtensionLooseRouting;
 
     typedef std::list<Ptr<Ipv6Interface> > Ipv6InterfaceList;
     typedef std::list<Ptr<Ipv6RawSocketImpl> > SocketList;
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-option.cc ns-3-ipv6-ext/src/internet-stack/ipv6-option.cc
--- ns-3-dev/src/internet-stack/ipv6-option.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-option.cc 2009-10-29 10:36:23.480461000 +0100
@@ -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@...>
+ */
+
+#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, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << 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, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << 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, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << 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, bool& isDropped)
+{
+  NS_LOG_FUNCTION (this << packet << offset << ipv6Header << isDropped);
+
+  Ptr<Packet> p = packet->Copy ();
+  p->RemoveAtStart (offset);
+
+  Ipv6OptionRouterAlertHeader routerAlertHeader;
+  p->RemoveHeader (routerAlertHeader);
+
+  isDropped = false;
+
+  return routerAlertHeader.GetSerializedSize ();
+}
+
+} /* namespace ns3 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-option-demux.cc ns-3-ipv6-ext/src/internet-stack/ipv6-option-demux.cc
--- ns-3-dev/src/internet-stack/ipv6-option-demux.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-option-demux.cc 2009-10-29 10:36:23.469477000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-option-demux.h ns-3-ipv6-ext/src/internet-stack/ipv6-option-demux.h
--- ns-3-dev/src/internet-stack/ipv6-option-demux.h 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-option-demux.h 2009-10-29 10:36:23.471459000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-option.h ns-3-ipv6-ext/src/internet-stack/ipv6-option.h
--- ns-3-dev/src/internet-stack/ipv6-option.h 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-option.h 2009-10-29 10:36:23.483461000 +0100
@@ -0,0 +1,269 @@
+/* -*-  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@...>
+ */
+
+#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 isDropped if the packet must be dropped
+     * \return the processed size
+     */
+    virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, 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 isDropped if the packet must be dropped
+     * \return the processed size
+     */
+    virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, 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 isDropped if the packet must be dropped
+     * \return the processed size
+     */
+    virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, 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 isDropped if the packet must be dropped
+     * \return the processed size
+     */
+    virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, 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 isDropped if the packet must be dropped
+     * \return the processed size
+     */
+    virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6Header const& ipv6Header, bool& isDropped);
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_OPTION_H */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-option-header.cc ns-3-ipv6-ext/src/internet-stack/ipv6-option-header.cc
--- ns-3-dev/src/internet-stack/ipv6-option-header.cc 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-option-header.cc 2009-10-29 10:36:23.474457000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/ipv6-option-header.h ns-3-ipv6-ext/src/internet-stack/ipv6-option-header.h
--- ns-3-dev/src/internet-stack/ipv6-option-header.h 1970-01-01 01:00:00.000000000 +0100
+++ ns-3-ipv6-ext/src/internet-stack/ipv6-option-header.h 2009-10-29 10:36:23.477460000 +0100
@@ -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@...>
+ */
+
+#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 */
+
diff -wrbBPu ns-3-dev/src/internet-stack/wscript ns-3-ipv6-ext/src/internet-stack/wscript
--- ns-3-dev/src/internet-stack/wscript 2009-10-23 16:01:58.950052000 +0200
+++ ns-3-ipv6-ext/src/internet-stack/wscript 2009-10-29 10:36:23.603452000 +0100
@@ -99,8 +99,8 @@
         'icmpv4.cc',
         'icmpv4-l4-protocol.cc',
         'loopback-net-device.cc',
-        'ipv6-interface.cc',
         'ndisc-cache.cc',
+        'ipv6-interface.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'
         ]
@@ -123,6 +129,7 @@
         'icmpv6-header.h',
         'ipv4-l3-protocol.h',
         'ipv6-l3-protocol.h',
+        'ipv6-extension-header.h',
         'arp-l3-protocol.h',
         'udp-l4-protocol.h',
         'tcp-l4-protocol.h',
diff -wrbBPu ns-3-dev/src/node/ipv6.h ns-3-ipv6-ext/src/node/ipv6.h
--- ns-3-dev/src/node/ipv6.h 2009-10-23 16:01:59.147052000 +0200
+++ ns-3-ipv6-ext/src/node/ipv6.h 2009-10-29 10:36:23.771453000 +0100
@@ -284,6 +284,16 @@
   virtual void SetForwarding (uint32_t interface, bool val) = 0;
 
   /**
+   * \brief Register the IPv6 Extensions.
+   */
+  virtual void RegisterExtensions () = 0;
+
+  /**
+   * \brief Register the IPv6 Options.
+   */
+  virtual void RegisterOptions () = 0;
+
+  /**
    * \brief Any interface magic number.
    */
   static const uint32_t IF_ANY = 0xffffffff;
diff -wrbBPu ns-3-dev/src/routing/static-routing/ipv6-static-routing.cc ns-3-ipv6-ext/src/routing/static-routing/ipv6-static-routing.cc
--- ns-3-dev/src/routing/static-routing/ipv6-static-routing.cc 2009-10-23 16:01:59.408054000 +0200
+++ ns-3-ipv6-ext/src/routing/static-routing/ipv6-static-routing.cc 2009-10-29 10:36:24.046452000 +0100
@@ -529,8 +527,8 @@
   {
     NS_LOG_LOGIC ("Multicast destination");
     Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (header.GetSourceAddress (),
-                                                    header.GetDestinationAddress ()
-                                                    , m_ipv6->GetInterfaceForDevice (idev));
+                                                    header.GetDestinationAddress (),
+                                                    m_ipv6->GetInterfaceForDevice (idev));
 
     if (mrtentry)
     {
diff -wrbBPu ns-3-dev/src/routing/static-routing/ipv6-static-routing.h ns-3-ipv6-ext/src/routing/static-routing/ipv6-static-routing.h
--- ns-3-dev/src/routing/static-routing/ipv6-static-routing.h 2009-10-23 16:01:59.411051000 +0200
+++ ns-3-ipv6-ext/src/routing/static-routing/ipv6-static-routing.h 2009-10-29 10:36:24.049452000 +0100
@@ -237,6 +237,14 @@
     virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
     virtual void SetIpv6 (Ptr<Ipv6> ipv6);
 
+    /**
+     * \brief Lookup in the forwarding table for destination.
+     * \param dest destination address
+     * \param interface output interface if any (put 0 otherwise)
+     * \return Ipv6Route to route the packet to reach dest address
+     */
+    Ptr<Ipv6Route> LookupStatic (Ipv6Address dest, uint32_t interface = 0);
+
   protected:
     /**
      * \brief Dispose this object.
@@ -253,14 +261,6 @@
     typedef std::list<Ipv6MulticastRoutingTableEntry *>::iterator MulticastRoutesI;
 
     /**
-     * \brief Lookup in the forwarding table for destination.
-     * \param dest destination address
-     * \param interface output interface if any (put 0 otherwise)
-     * \return Ipv6Route to route the packet to reach dest address
-     */
-    Ptr<Ipv6Route> LookupStatic (Ipv6Address dest, uint32_t interface = 0);
-
-    /**
      * \brief Lookup in the multicast forwarding table for destination.
      * \param origin source address
      * \param group group multicast address

Re: Ipv6Extension (was UDPv6, missleading subject)

by Fabian Mauchle :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I did that because Ipv6Extensios and Ipv6Options are currently treated
independently, which they aren’t.

So my changes are:
- Add a relationship between Ipv6ExtensionHeader and Ipv6OptionHeader, with
the possibility to add Option headers to Extension Headers. This also
automates the Header alignment required by IPv6. (I implemented this some
time ago, based on the old IPv6 repo from Sebastien)

- Because options are often used to store additional information for
processing extensions, the independent processing of options does not suit
this very well. So I replaced the Ipv6OptionDemux by a list of Callbacks,
registered by the Ipv6Extension and called for each Ipv6OptionHeader present
(identified by the type field).

Regards,
Fabian


-----Ursprüngliche Nachricht-----
Von: ns-developers-bounces@... [mailto:ns-developers-bounces@...] Im
Auftrag von Faker Moatamri
Gesendet: Donnerstag, 29. Oktober 2009 11:36
An: vincent@...
Cc: ns-developers@...; ns-3-reviews@...
Betreff: Re: [Ns-developers] UDPv6

Sébastien Vincent wrote:

> Hi,
>
> Tom Henderson a écrit :
>> Fabian Mauchle wrote:
>>> Hi Sebastien, Hi all,
>>>
>>> As we are heading on with merging more of Ipv6, I just wondered
>>> about UDPv6.
>>> What is the current state of this, and will it be included in ns3.7?
>>
>> Fabian, this is the most recent update that has been on the list, and
>> I'm not aware of any recent change:
>> http://mailman.isi.edu/pipermail/ns-developers/2009-July/006211.html
>>
>
> I have not started anything on UDP/TCP refactoring and I'm affraid I
> will not have time to work on it until december/january.
> I prefer to take my little free time for merge IPv6 extension in
> ns-3.7 (available at https://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext).
>
I prepared a patch based on the above repository which is included in the
mail.
I also uploaded the code change in Rietveld so it is easier to review:
http://codereview.appspot.com/144048
I will be reviewing the code very soon. Tom, Craig, can you give a quick
review to the code?
Anyone else can review the code?

> Fabian has proposed to remove "IPv6 option demux" design from above
> source tree. His repository is located at
> http://sinv-56031.edu.hsr.ch/hg/ns-3-ipv6-ext. So feel free to review
> these repositories and give feedback about the two solutions.
Is there any reason why he did that? reviewing the first code is enough
right?
Best regards
Faker Moatamri




Re: Ipv6Extension (was UDPv6, missleading subject)

by Faker Moatamri :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fabian Mauchle wrote:

> Hi,
>
> I did that because Ipv6Extensios and Ipv6Options are currently treated
> independently, which they aren’t.
>
> So my changes are:
> - Add a relationship between Ipv6ExtensionHeader and Ipv6OptionHeader, with
> the possibility to add Option headers to Extension Headers. This also
> automates the Header alignment required by IPv6. (I implemented this some
> time ago, based on the old IPv6 repo from Sebastien)
>
> - Because options are often used to store additional information for
> processing extensions, the independent processing of options does not suit
> this very well. So I replaced the Ipv6OptionDemux by a list of Callbacks,
> registered by the Ipv6Extension and called for each Ipv6OptionHeader present
> (identified by the type field).
>  
Thanks for the explanation. It is clear that we can't merge both codes
in the main tree, so which version should be taken as a merge candidate?

Sebastian, I reviewed your code in
https://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext :
you will find all my comment in http://codereview.appspot.com/144048
The code is overall good, here is my most important remarks:
- Some code should contain more doxygen
- When you use new, be sure that somewhere you delete
- Coding style specially in indentation of header files
Best regards
Faker Moatamri


Re: Ipv6Extension (was UDPv6, missleading subject)

by Fabian Mauchle :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi All,

I looked over it again, and I'm not sure if removing the OptionDemux could
limit the flexibility it currently provides. So I've put together my old
Extension-Option link. You can find the code at
http://sinv-56031.edu.hsr.ch/hg/ns-3-ipv6-option.

The modification mainly simplifies the Assembly of Extension- and Option
Headers. It leaves the OptionDemux as is, and only extends the
Ipv6ExtensionHeader and Ipv6OptionHeader. It also includes a small
refactoring to remove duplicate code in the Ipv6Extension* subclasses.

So for now, I would propose to us this as a merge candidate.

What do you think?
Sebastien?

Regards,

Fabian


-----Ursprüngliche Nachricht-----
Von: Faker Moatamri [mailto:faker.moatamri@...]
Gesendet: Freitag, 30. Oktober 2009 12:41
An: Mauchle Fabian (f1mauchl@...)
Cc: vincent@...; ns-developers@...;
ns-3-reviews@...
Betreff: Re: AW: [Ns-developers] Ipv6Extension (was UDPv6, missleading
subject)
...
Thanks for the explanation. It is clear that we can't merge both codes
in the main tree, so which version should be taken as a merge candidate?
...

Best regards
Faker Moatamri




Re: IPv6 extension support

by Tom Henderson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sebastien Vincent wrote:

> Hi,
>
> Here is the repository for IPv6 extension support:
> http://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext/
>
> It contains two new examples:
> - fragmentation-ipv6, a node sends packets > MTU, packets are fragmented
> in IPv6 stack;
> - loose-routing-ipv6, a node sends special ICMPv6 which have IPv6
> routing header type 0 (it choose the router path).
>
> There are some stuff that could/have to be enhanced:
> - In ipv6-static-routing.cc, class Ipv6LooseRoutingExtension send
> directly the packets instead of passing up to Ipv6L3Protocol and it need
> Ipv6StaticRouting object to have a lookup (StaticLookup) in routing
> table (I don't need LocalDeliver/IpForward, ... callbacks). To do this I
> copy code from Ipv6RoutingHelper to get Ipv6StaticRouting object from
> Ipv6L3Protocol::GetRoutingProtocol. So we have the following choices:
>  - include an helper class in stack (not sure it is good);
>  - refactor to pass processed packets with routing header in IPv6 stack
> (tag, ...);
Can the RouteInput method demux the routing headers (without tag) and
forward on the routing header instead of the IPv6 header, since it gets
the packet?  I am suspicious of putting in these static routing methods
because it may not be static routing that is operating on the packet.
It seems to me that routing headers can be processed from within
RouteInput, and destination headers can be processed in LocalDeliver.

>  - add a virtual method in Ipv6RoutingProtocol that just look in routing
> table for a destination (stuff like RouteInput() with no callback) and
> returns a route.
Can RouteOutput() be used for these use cases?

- Tom


Re: Ipv6Extension (was UDPv6, missleading subject)

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Repository and codereview has been updated.

It remains doxygen to do and remove duplicate code in Ipv6Extension
(Fabian has already done this part so I will take it).

Regards,
--
Sebastien

Faker Moatamri a écrit :

> Fabian Mauchle wrote:
>> Hi,
>>
>> I did that because Ipv6Extensios and Ipv6Options are currently treated
>> independently, which they aren’t.
>> So my changes are:
>> - Add a relationship between Ipv6ExtensionHeader and
>> Ipv6OptionHeader, with
>> the possibility to add Option headers to Extension Headers. This also
>> automates the Header alignment required by IPv6. (I implemented this
>> some
>> time ago, based on the old IPv6 repo from Sebastien)
>>
>> - Because options are often used to store additional information for
>> processing extensions, the independent processing of options does not
>> suit
>> this very well. So I replaced the Ipv6OptionDemux by a list of
>> Callbacks,
>> registered by the Ipv6Extension and called for each Ipv6OptionHeader
>> present
>> (identified by the type field).
>>  
> Thanks for the explanation. It is clear that we can't merge both codes
> in the main tree, so which version should be taken as a merge candidate?
>
> Sebastian, I reviewed your code in
> https://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext :
> you will find all my comment in http://codereview.appspot.com/144048
> The code is overall good, here is my most important remarks:
> - Some code should contain more doxygen
> - When you use new, be sure that somewhere you delete
> - Coding style specially in indentation of header files
> Best regards
> Faker Moatamri
>
>


Re: Ipv6Extension (was UDPv6, missleading subject)

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Fabian,

Fabian Mauchle a écrit :

> Hi All,
>
> I looked over it again, and I'm not sure if removing the OptionDemux could
> limit the flexibility it currently provides. So I've put together my old
> Extension-Option link. You can find the code at
> http://sinv-56031.edu.hsr.ch/hg/ns-3-ipv6-option.
>
> The modification mainly simplifies the Assembly of Extension- and Option
> Headers. It leaves the OptionDemux as is, and only extends the
> Ipv6ExtensionHeader and Ipv6OptionHeader. It also includes a small
> refactoring to remove duplicate code in the Ipv6Extension* subclasses.
>
> So for now, I would propose to us this as a merge candidate.
>
> What do you think?
> Sebastien?
>
>  

I am very busy this week so I will try to review it by the end of week.
And I will apply today the "code duplication fix" part of your patch.

Regards,
--
Sebastien


> Regards,
>
> Fabian
>
>
> -----Ursprüngliche Nachricht-----
> Von: Faker Moatamri [mailto:faker.moatamri@...]
> Gesendet: Freitag, 30. Oktober 2009 12:41
> An: Mauchle Fabian (f1mauchl@...)
> Cc: vincent@...; ns-developers@...;
> ns-3-reviews@...
> Betreff: Re: AW: [Ns-developers] Ipv6Extension (was UDPv6, missleading
> subject)
> ...
> Thanks for the explanation. It is clear that we can't merge both codes
> in the main tree, so which version should be taken as a merge candidate?
> ...
>
> Best regards
> Faker Moatamri
>
>
>
>  


Re: IPv6 extension support

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Tom,

Tom Henderson a écrit :

> Sebastien Vincent wrote:
>> Hi,
>>
>> Here is the repository for IPv6 extension support:
>> http://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext/
>>
>> It contains two new examples:
>> - fragmentation-ipv6, a node sends packets > MTU, packets are
>> fragmented in IPv6 stack;
>> - loose-routing-ipv6, a node sends special ICMPv6 which have IPv6
>> routing header type 0 (it choose the router path).
>>
>> There are some stuff that could/have to be enhanced:
>> - In ipv6-static-routing.cc, class Ipv6LooseRoutingExtension send
>> directly the packets instead of passing up to Ipv6L3Protocol and it
>> need Ipv6StaticRouting object to have a lookup (StaticLookup) in
>> routing table (I don't need LocalDeliver/IpForward, ... callbacks).
>> To do this I copy code from Ipv6RoutingHelper to get
>> Ipv6StaticRouting object from Ipv6L3Protocol::GetRoutingProtocol. So
>> we have the following choices:
>>  - include an helper class in stack (not sure it is good);
>>  - refactor to pass processed packets with routing header in IPv6
>> stack (tag, ...);
> Can the RouteInput method demux the routing headers (without tag) and
> forward on the routing header instead of the IPv6 header, since it
> gets the packet?  I am suspicious of putting in these static routing
> methods because it may not be static routing that is operating on the
> packet. It seems to me that routing headers can be processed from
> within RouteInput, and destination headers can be processed in
> LocalDeliver.

The routing extension are  processed in a local delivered packet, see
RFC2460 section 4.4 :

 A Routing header is not examined or processed until it reaches the
   node identified in the Destination Address field of the IPv6 header.



>
>>  - add a virtual method in Ipv6RoutingProtocol that just look in
>> routing table for a destination (stuff like RouteInput() with no
>> callback) and returns a route.
> Can RouteOutput() be used for these use cases?

Oh I forget this method... yes it could work, I will test it.

Regards,
--
Sebastien

>
> - Tom
>
>


Re: Ipv6Extension (was UDPv6, missleading subject)

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I merge Fabian's repository (ns-3-ipv6-option) into ns-3-ipv6-ext
repository (http://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext). I also fix
comments from codereview.

Best regards,
--
Sebastien

Sébastien Vincent a écrit :

> Hi Fabian,
>
> Fabian Mauchle a écrit :
>> Hi All,
>>
>> I looked over it again, and I'm not sure if removing the OptionDemux
>> could
>> limit the flexibility it currently provides. So I've put together my old
>> Extension-Option link. You can find the code at
>> http://sinv-56031.edu.hsr.ch/hg/ns-3-ipv6-option.
>>
>> The modification mainly simplifies the Assembly of Extension- and Option
>> Headers. It leaves the OptionDemux as is, and only extends the
>> Ipv6ExtensionHeader and Ipv6OptionHeader. It also includes a small
>> refactoring to remove duplicate code in the Ipv6Extension* subclasses.
>>
>> So for now, I would propose to us this as a merge candidate.
>>
>> What do you think?
>> Sebastien?
>>
>>  
>
> I am very busy this week so I will try to review it by the end of
> week. And I will apply today the "code duplication fix" part of your
> patch.
>
> Regards,
> --
> Sebastien
>
>
>> Regards,
>>
>> Fabian
>>
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Faker Moatamri [mailto:faker.moatamri@...] Gesendet:
>> Freitag, 30. Oktober 2009 12:41
>> An: Mauchle Fabian (f1mauchl@...)
>> Cc: vincent@...; ns-developers@...;
>> ns-3-reviews@...
>> Betreff: Re: AW: [Ns-developers] Ipv6Extension (was UDPv6, missleading
>> subject)
>> ...
>> Thanks for the explanation. It is clear that we can't merge both
>> codes in the main tree, so which version should be taken as a merge
>> candidate?
>> ...
>>
>> Best regards
>> Faker Moatamri
>>
>>
>>
>>  
>
>


Re: Ipv6Extension (was UDPv6, missleading subject)

by Tom Henderson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Sébastien Vincent wrote:
> Hi,
>
> I merge Fabian's repository (ns-3-ipv6-option) into ns-3-ipv6-ext
> repository (http://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext). I also fix
> comments from codereview.

Fabian and Sebastien,

I reviewed this again tonight.  My main remaining comments are:

1) I would recommend some test code coverage for some of this
(particularly fragmentation).  I didn't notice any new tests added for
these extensions.

2) coding style for the new files; we indent the braces such as the gnu
indent program -bl or -bli2 options:

                if (x > 0)
                  {
                    x--;
                  }

3) when you merge, please update RELEASE_NOTES and CHANGES.html

Regards,
Tom

Re: Ipv6Extension (was UDPv6, missleading subject)

by Sébastien Vincent :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Tom,

Tom Henderson a écrit :

> Sébastien Vincent wrote:
>> Hi,
>>
>> I merge Fabian's repository (ns-3-ipv6-option) into ns-3-ipv6-ext
>> repository (http://svnet.u-strasbg.fr/hg/ns-3-ipv6-ext). I also fix
>> comments from codereview.
>
> Fabian and Sebastien,
>
> I reviewed this again tonight.  My main remaining comments are:
>
> 1) I would recommend some test code coverage for some of this
> (particularly fragmentation).  I didn't notice any new tests added for
> these extensions.
>

I will try to do something next week.

> 2) coding style for the new files; we indent the braces such as the
> gnu indent program -bl or -bli2 options:
>
>                if (x > 0)
>                  {
>                    x--;
>                  }
>

Done.

> 3) when you merge, please update RELEASE_NOTES and CHANGES.html
>

OK.

--
Sebastien

> Regards,
> Tom
>


WiMAX merge

by iamine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Tom and All,

I have pushed a new version of the wimax module to
http://code.nsnam.org/iamine/ns-3-wimax-release/. This new version provides:

1) 4 test suites for wimax
  - ns3-wimax-qos including 3 test cases
  - wimax-phy-layer including  2 test cases
  - wimax-bs-mac-layer including 2 test cases
  - wimax-ss-mac-layer including 5 test cases
2) Adding more attributes to the following classes:
 - wimax-ss-net-device: 17 Attributes
 - wimax-bs-net-device: 13 Attributes
 - simple-ofdm-wimax-phy: 7 Attributes
3) Aligning trace sources of wimax-ss-net-device, wimax-bs-net-device
and wimax-phy  with trace sources of  the wifi module

The module has been merged with the latest ns-3-dev version (changeset
5754) and has been successfully compiled under g++4.2.4, 4.3.3 and 4.4.0
in both debug and optimized mode. The examples I have developed have
been successfully executed with valgrind which reports 0 error.

I would like to ask you kindly to review this module.

Thank you
Regards
Amine