diff -uprN ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-interface.cc ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-interface.cc
--- ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-interface.cc	2013-12-20 18:44:50.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-interface.cc	2014-02-17 09:49:52.827965144 +0100
@@ -240,6 +240,8 @@ Ipv6InterfaceAddress Ipv6Interface::GetL
 
   for (Ipv6InterfaceAddressListCI it = m_addresses.begin (); it != m_addresses.end (); ++it)
     {
+	  //DEBUG
+	  NS_LOG_INFO ("Addr: " << (*it).GetAddress ());
       if ((*it).GetAddress ().IsLinkLocal ())
         {
           return (*it);
@@ -342,8 +344,14 @@ Ipv6InterfaceAddress Ipv6Interface::GetA
         }
     }
 
-  /*  NS_ASSERT_MSG (false, "Not matching address."); */
-  Ipv6InterfaceAddress ret;
+  //FPMIPv6-S Implementation by Abdelwahed {
+  // If no matching global address for NS source address
+  // we use Link-Local Address instead
+  Ipv6InterfaceAddress ret = *m_addresses.begin();
+  //----OLD-----
+  // /*  NS_ASSERT_MSG (false, "Not matching address."); */
+  // Ipv6InterfaceAddress ret;
+  //}
   return ret; /* quiet compiler */
 }
 
diff -uprN ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-l4-protocol.h ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-l4-protocol.h
--- ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-l4-protocol.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-l4-protocol.h	2012-03-02 10:29:59.000000000 +0100
@@ -0,0 +1,109 @@
+/* -*- 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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
+ */
+
+#ifndef IPV6_L4_PROTOCOL_H
+#define IPV6_L4_PROTOCOL_H
+
+#include "ns3/object.h"
+#include "ns3/ipv6-header.h"
+
+namespace ns3
+{
+
+class Packet;
+class Ipv6Address;
+class Ipv6Interface;
+
+/**
+ * \class Ipv6L4Protocol
+ * \brief IPv6 L4 protocol abstract class
+ */
+class Ipv6L4Protocol : public Object
+{
+public:
+  /**
+   * \enum RxStatus_e
+   * \brief Status of receive.
+   */
+  enum RxStatus_e 
+  {
+    RX_OK, /**< Receive OK */
+    RX_CSUM_FAILED, /**< Checksum of layer 4 protocol failed */
+    RX_ENDPOINT_UNREACH /**< Destination unreachable */
+  };
+
+  /**
+   * \brief Get the type identifier.
+   * \return type identifier
+   */
+  static TypeId GetTypeId (void);
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6L4Protocol ();
+
+  /**
+   * \brief Get the protocol number.
+   * \return protocol number
+   */
+  virtual int GetProtocolNumber () const = 0;
+
+  /**
+   * \brief Receive method.
+   *
+   * Called from lower-level layers to send the packet up
+   * in the stack.
+   * \param p packet to forward up
+   * \param src source address of packet received
+   * \param dst address of packet received
+   * \param incomingInterface the Ipv6Interface on which the packet arrived
+   * \return status (OK, destination unreachable or checksum failed)
+   */
+  virtual enum RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src, 
+                                   Ipv6Address const &dst, 
+                                   Ptr<Ipv6Interface> incomingInterface) = 0;
+
+  /**
+   * \brief ICMPv6 receive method.
+   * \param icmpSource the source address of the ICMPv6 message
+   * \param icmpTtl the ttl of the ICMPv6 message
+   * \param icmpType the 'type' field of the ICMPv6 message
+   * \param icmpCode the 'code' field of the ICMPv6 message
+   * \param icmpInfo extra information dependent on the ICMPv6 message
+   *        generated by Icmpv6L4Protocol
+   * \param payloadSource the source address of the packet which triggered
+   *        the ICMPv6 message
+   * \param payloadDestination the destination address of the packet which
+   *        triggered the ICMPv6 message.
+   * \param payload the first 8 bytes of the UDP header of the packet
+   *        which triggered the ICMPv6 message.
+   */
+  virtual void ReceiveIcmp (Ipv6Address icmpSource, uint8_t icmpTtl,
+                            uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
+                            Ipv6Address payloadSource, Ipv6Address payloadDestination,
+                            const uint8_t* payload);
+
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_L4_PROTOCOL_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-mobility-option.h ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-mobility-option.h
--- ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-mobility-option.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/internet/model/ipv6-mobility-option.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,485 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#ifndef IPV6_MOBILITY_OPTION_H
+#define IPV6_MOBILITY_OPTION_H
+
+#include <list>
+
+#include "ns3/object.h"
+#include "ns3/node.h"
+#include "ns3/ptr.h"
+#include "ns3/header.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/nstime.h"
+#include "ns3/identifier.h"
+
+namespace ns3
+{
+
+class Ipv6MobilityOptionBundle;
+
+/**
+ * \class Ipv6MobilityOption
+ * \brief Ipv6 Mobility Option base
+ *
+ * If you want to implement a new Ipv6 Mobility option, all you have to do is
+ * implement a subclass of this class and add it to an Ipv6MobilityOptionDemux.
+ */
+class Ipv6MobilityOption : public Object
+{
+public:
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOption ();
+  
+  /**
+   * \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 GetMobilityOptionNumber () const = 0;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle) = 0;
+  
+private:
+  /**
+   * \brief The node.
+   */
+  Ptr<Node> m_node;
+};
+
+class Ipv6MobilityOptionBundle
+{
+public:
+  Ipv6MobilityOptionBundle();
+  
+  Identifier GetMnIdentifier() const;
+  void SetMnIdentifier(Identifier mnId);
+  
+  Identifier GetMnLinkIdentifier() const;
+  void SetMnLinkIdentifier(Identifier mnLinkId);
+  
+  std::list<Ipv6Address> GetHomeNetworkPrefixes() const;
+  void SetHomeNetworkPrefixes(std::list<Ipv6Address> hnps);
+  void AddHomeNetworkPrefix(Ipv6Address addr);
+  
+  Ipv6Address GetMagLinkAddress() const;
+  void SetMagLinkAddress(Ipv6Address lla);
+  
+  uint8_t GetAccessTechnologyType() const;
+  void SetAccessTechnologyType(uint8_t att);
+  
+  uint8_t GetHandoffIndicator() const;
+  void SetHandoffIndicator(uint8_t hi);
+  
+  Time GetTimestamp() const;
+  void SetTimestamp(Time tm);
+  
+protected:
+private:
+  //for PMIPv6
+  Identifier m_mnIdentifier;
+  Identifier m_mnLinkIdentifier;
+  std::list<Ipv6Address> m_homeNetworkPrefixes;
+  Ipv6Address m_magLinkAddress;
+  uint8_t m_accessTechnologyType;
+  uint8_t m_handoffIndicator;
+  Time m_timestamp;
+};
+
+/**
+ * \class Ipv6MobilityOptionPad1
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionPad1 : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 0;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionPad1 ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionPadn
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionPadn : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 1;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionPadn ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionMobileNodeIdentifier
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionMobileNodeIdentifier : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 8;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionMobileNodeIdentifier ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionHomeNetworkPrefix
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionHomeNetworkPrefix : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 22;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionHomeNetworkPrefix ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionHandoffIndicator
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionHandoffIndicator : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 23;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionHandoffIndicator ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionAccessTechnologyType
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionAccessTechnologyType : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 24;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionAccessTechnologyType ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionMobileNodeLinkLayerIdentifier
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionMobileNodeLinkLayerIdentifier : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 25;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionMobileNodeLinkLayerIdentifier ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionLinkLocalAddress
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionLinkLocalAddress : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 26;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionLinkLocalAddress ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionTimestamp
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionTimestamp : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 27;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionTimestamp ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_MOBILITY_OPTION_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/internet/wscript ns-allinone-3.19/ns-3.19/src/internet/wscript
--- ns-allinone-3.19/ns-3.19/src/internet/wscript	2013-12-20 18:44:50.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/internet/wscript	2014-02-17 09:55:11.989547783 +0100
@@ -203,9 +203,7 @@ def build(bld):
         'test/ipv4-packet-info-tag-test-suite.cc',
         'test/ipv4-raw-test.cc',
         'test/ipv4-header-test.cc',
-        'test/ipv4-fragmentation-test.cc',
         'test/ipv4-forwarding-test.cc',
-        'test/error-channel.cc',
         'test/ipv4-test.cc',
         'test/ipv6-extension-header-test-suite.cc',
         'test/ipv6-list-routing-test-suite.cc',

diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.cc ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,94 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include <vector>
+
+#include "ns3/log.h"
+#include "ns3/ptr.h"
+#include "ns3/names.h"
+#include "ns3/node.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/assert.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+#include "ipv6-static-source-routing-helper.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticSourceRoutingHelper");
+
+namespace ns3 {
+
+Ipv6StaticSourceRoutingHelper::Ipv6StaticSourceRoutingHelper ()
+{}
+
+Ipv6StaticSourceRoutingHelper::Ipv6StaticSourceRoutingHelper (const Ipv6StaticSourceRoutingHelper &o)
+{
+}
+
+Ipv6StaticSourceRoutingHelper* 
+Ipv6StaticSourceRoutingHelper::Copy (void) const 
+{
+  return new Ipv6StaticSourceRoutingHelper (*this); 
+}
+
+Ptr<Ipv6RoutingProtocol> 
+Ipv6StaticSourceRoutingHelper::Create (Ptr<Node> node) const
+{
+  return CreateObject<Ipv6StaticSourceRouting> ();
+}
+
+Ptr<Ipv6StaticSourceRouting>
+Ipv6StaticSourceRoutingHelper::GetStaticSourceRouting (Ptr<Ipv6> ipv6) const
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Ipv6RoutingProtocol> ipv6rp = ipv6->GetRoutingProtocol ();
+  NS_ASSERT_MSG (ipv6rp, "No routing protocol associated with Ipv6");
+  if (DynamicCast<Ipv6StaticSourceRouting> (ipv6rp))
+    {
+      NS_ASSERT_MSG (false, "Static source routing cannot exist main routing protocol");
+      return 0;
+    } 
+	
+  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<Ipv6StaticSourceRouting> (temp))
+            {
+              NS_LOG_LOGIC ("Found static routing in list");
+              return DynamicCast<Ipv6StaticSourceRouting> (temp);
+            }
+        }
+    }
+  NS_LOG_LOGIC ("Static routing not found");
+  return 0;
+}
+
+} // namespace ns3
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.h ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/helper/ipv6-static-source-routing-helper.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,97 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_STATIC_SOURCE_ROUTING_HELPER_H
+#define IPV6_STATIC_SOURCE_ROUTING_HELPER_H
+
+#include "ns3/ipv6.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/ipv6-routing-helper.h"
+
+#include "ns3/ipv6-static-source-routing.h"
+
+namespace ns3 {
+
+/**
+ * \brief Helper class that adds ns3::Ipv6StaticSourceRouting objects
+ *
+ * This class is expected to be used in conjunction with 
+ * ns3::InternetStackHelper::SetRoutingHelper
+ */
+class Ipv6StaticSourceRoutingHelper : public Ipv6RoutingHelper
+{
+public:
+  /**
+   * \brief Constructor.
+   */
+  Ipv6StaticSourceRoutingHelper ();
+
+  /**
+   * \brief Construct an Ipv6ListRoutingHelper from another previously 
+   * initialized instance (Copy Constructor).
+   */
+  Ipv6StaticSourceRoutingHelper (const Ipv6StaticSourceRoutingHelper &);
+
+  /**
+   * \internal
+   * \returns pointer to clone of this Ipv6StaticSourceRoutingHelper
+   *
+   * This method is mainly for internal use by the other helpers;
+   * clients are expected to free the dynamic memory allocated by this method
+   */
+  Ipv6StaticSourceRoutingHelper* Copy (void) const;
+
+  /**
+   * \param node the node on which the routing protocol will run
+   * \returns a newly-created routing protocol
+   *
+   * This method will be called by ns3::InternetStackHelper::Install
+   */
+  virtual Ptr<Ipv6RoutingProtocol> Create (Ptr<Node> node) const;
+
+  /**
+   * \brief Get Ipv6StaticRouting pointer from IPv6 stack.
+   * \param ipv6 Ipv6 pointer
+   * \return Ipv6StaticRouting pointer or 0 if not exist
+   */
+  Ptr<Ipv6StaticSourceRouting> GetStaticSourceRouting (Ptr<Ipv6> ipv6) const;
+
+private:
+  /**
+   * \internal
+   * \brief Assignment operator declared private and not implemented to disallow
+   * assignment and prevent the compiler from happily inserting its own.
+   */
+  Ipv6StaticSourceRoutingHelper &operator = (const Ipv6StaticSourceRoutingHelper &o);
+};
+
+} // namespace ns3
+
+#endif /* IPV6_STATIC_SOURCE_ROUTING_HELPER_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.cc ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.cc	2014-01-27 11:06:04.000000000 +0100
@@ -0,0 +1,304 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/object.h"
+#include "ns3/names.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv6.h"
+#include "ns3/packet-socket-factory.h"
+#include "ns3/config.h"
+#include "ns3/simulator.h"
+#include "ns3/string.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/node.h"
+#include "ns3/core-config.h"
+#include "ns3/arp-l3-protocol.h"
+#include "ns3/ipv6-mobility-l4-protocol.h"
+#include "ns3/ipv6-mobility-header.h"
+#include "ns3/ipv6-mobility-option-header.h"
+#include "ns3/ipv6-mobility-option.h"
+#include "ns3/pmipv6-mag.h"
+#include "ns3/pmipv6-lma.h"
+#include "ns3/pmipv6-mag-notifier.h"
+#include "ns3/pmipv6-profile.h"
+#include "ns3/identifier.h"
+#include "ns3/ipv6-tunnel-l4-protocol.h"
+#include "ns3/pmipv6-prefix-pool.h"
+
+#include "ns3/ipv6-list-routing.h"
+#include "ns3/ipv6-static-source-routing.h"
+
+#include "pmip6-helper.h"
+#include <limits>
+#include <map>
+
+NS_LOG_COMPONENT_DEFINE ("Pmip6Helper");
+
+namespace ns3 {
+
+Pmip6LmaHelper::Pmip6LmaHelper()
+ : m_profile(0),
+   m_prefixBegin("3ffe:1:4::"),
+   m_prefixBeginLen(48)
+{
+}
+
+Pmip6LmaHelper::~Pmip6LmaHelper()
+{
+}
+
+void
+Pmip6LmaHelper::Install (Ptr<Node> node) const
+{
+  Ptr<Ipv6MobilityL4Protocol> mipv6 = node->GetObject<Ipv6MobilityL4Protocol>();
+
+  if(mipv6 != 0)
+    {
+      mipv6 = CreateObject<Ipv6MobilityL4Protocol>();
+  
+      node->AggregateObject(mipv6);
+  
+	  mipv6 = node->GetObject<Ipv6MobilityL4Protocol>();
+  
+      mipv6->RegisterMobility();
+      mipv6->RegisterMobilityOptions();
+	}
+	
+  Ptr<Ipv6TunnelL4Protocol> ip6tunnel = node->GetObject<Ipv6TunnelL4Protocol>();
+  
+  if ( ip6tunnel == 0 )
+    {
+	  ip6tunnel = CreateObject<Ipv6TunnelL4Protocol>();
+	  
+	  node->AggregateObject (ip6tunnel);
+	}
+  
+  Ptr<Pmipv6Lma> lma = CreateObject<Pmipv6Lma>();
+  
+  if(m_profile == 0)
+    {
+      lma->SetProfile (m_profile->GetProfile());
+    }
+  else
+    {
+	  lma->SetProfile (CreateObject<Pmipv6Profile> ());
+	}  
+	
+  lma->SetPrefixPool (Create<Pmipv6PrefixPool> (m_prefixBegin, m_prefixBeginLen));
+  
+  node->AggregateObject(lma);
+}
+
+void Pmip6LmaHelper::SetProfileHelper(Pmip6ProfileHelper *pf)
+{
+  m_profile = pf;
+}
+  
+void Pmip6LmaHelper::SetPrefixPoolBase(Ipv6Address prefixBegin, uint8_t prefixLen)
+{
+  m_prefixBegin = prefixBegin;
+  m_prefixBeginLen = prefixLen;
+}
+
+Pmip6MagHelper::Pmip6MagHelper()
+: m_profile(0)
+{
+}
+
+Pmip6MagHelper::~Pmip6MagHelper()
+{
+}
+
+void
+Pmip6MagHelper::Install (Ptr<Node> node) const
+{
+  Ptr<Ipv6MobilityL4Protocol> mipv6 = node->GetObject<Ipv6MobilityL4Protocol>();
+
+  if(mipv6 != 0)
+    {
+      mipv6 = CreateObject<Ipv6MobilityL4Protocol>();
+  
+      node->AggregateObject(mipv6);
+	  
+	  mipv6 = node->GetObject<Ipv6MobilityL4Protocol>();
+  
+      mipv6->RegisterMobility();
+      mipv6->RegisterMobilityOptions();
+	}
+
+  Ptr<Ipv6TunnelL4Protocol> ip6tunnel = node->GetObject<Ipv6TunnelL4Protocol>();
+  
+  if (ip6tunnel != 0 )
+    {
+	  ip6tunnel = CreateObject<Ipv6TunnelL4Protocol>();
+	  
+	  node->AggregateObject (ip6tunnel);
+	}
+
+  Ptr<Pmipv6Mag> mag = CreateObject<Pmipv6Mag>();
+  
+  mag->UseRemoteAP(false);
+
+  if(m_profile != 0)
+    {
+      mag->SetProfile(m_profile->GetProfile());
+    }
+  else
+    {
+	  mag->SetProfile(CreateObject<Pmipv6Profile>());
+	}
+	
+  //Attach static source routing
+  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
+  
+  NS_ASSERT_MSG(ipv6, "Install Internet-stack first before installing PMIPv6-related agents");
+  
+  Ptr<Ipv6RoutingProtocol> routingProtocol = ipv6->GetRoutingProtocol();
+  Ptr<Ipv6ListRouting> listRouting = DynamicCast<Ipv6ListRouting>(routingProtocol);
+  
+  NS_ASSERT_MSG( listRouting, "PMIPv6 needs Ipv6-list-routing protocol for operation");
+  
+  Ptr<Ipv6StaticSourceRouting> sourceRouting = CreateObject<Ipv6StaticSourceRouting>();
+  
+  listRouting->AddRoutingProtocol(sourceRouting, 10); //higher priority than static routing
+	
+  node->AggregateObject(mag);
+}
+
+void
+Pmip6MagHelper::Install (Ptr<Node> node, Ipv6Address target, NodeContainer aps) const
+{
+  Ptr<Ipv6MobilityL4Protocol> mipv6 = node->GetObject<Ipv6MobilityL4Protocol>();
+
+  if(mipv6 == 0)
+    {
+      mipv6 = CreateObject<Ipv6MobilityL4Protocol>();
+  
+      node->AggregateObject(mipv6);
+	  
+	  mipv6 = node->GetObject<Ipv6MobilityL4Protocol>();
+  
+      mipv6->RegisterMobility();
+      mipv6->RegisterMobilityOptions();
+	}
+
+  Ptr<Ipv6TunnelL4Protocol> ip6tunnel = node->GetObject<Ipv6TunnelL4Protocol>();
+  
+  if ( ip6tunnel == 0 )
+    {
+	  ip6tunnel = CreateObject<Ipv6TunnelL4Protocol>();
+	  
+	  node->AggregateObject (ip6tunnel);
+	}
+	
+  //setup notifier receiver
+  Ptr<Pmipv6MagNotifier> noti = CreateObject<Pmipv6MagNotifier>();
+  node->AggregateObject(noti);
+  
+  //setup notifier sender
+  for (NodeContainer::Iterator i = aps.Begin (); i != aps.End (); ++i)
+    {
+	  noti = CreateObject<Pmipv6MagNotifier>();
+	  
+	  noti->SetTargetAddress(target);
+	  
+	  (*i)->AggregateObject(noti);
+    }
+
+  //----------------------
+  Ptr<Pmipv6Mag> mag = CreateObject<Pmipv6Mag>();
+  
+  mag->UseRemoteAP(true);
+  
+  if(m_profile != 0)
+    {
+      mag->SetProfile(m_profile->GetProfile());
+    }
+  else
+    {
+	  mag->SetProfile(CreateObject<Pmipv6Profile>());
+	}
+
+  //Attach static source routing
+  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6>();
+  
+  NS_ASSERT_MSG(ipv6, "Install Internet-stack first before installing PMIPv6-related agents");
+  
+  Ptr<Ipv6RoutingProtocol> routingProtocol = ipv6->GetRoutingProtocol();
+  Ptr<Ipv6ListRouting> listRouting = DynamicCast<Ipv6ListRouting>(routingProtocol);
+  
+  NS_ASSERT_MSG( listRouting, "PMIPv6 needs Ipv6-list-routing protocol for operation");
+  
+  Ptr<Ipv6StaticSourceRouting> sourceRouting = CreateObject<Ipv6StaticSourceRouting>();
+  
+  listRouting->AddRoutingProtocol(sourceRouting, 10); //higher priority than static routing
+  
+  node->AggregateObject(mag);
+  
+}
+
+void 
+Pmip6MagHelper::SetProfileHelper(Pmip6ProfileHelper *pf)
+{
+  m_profile = pf;
+}
+
+Pmip6ProfileHelper::Pmip6ProfileHelper()
+{
+  m_profile = CreateObject<Pmipv6Profile>();
+}
+
+Pmip6ProfileHelper::~Pmip6ProfileHelper()
+{
+}
+
+Ptr<Pmipv6Profile> Pmip6ProfileHelper::GetProfile()
+{
+  return m_profile;
+}
+
+void Pmip6ProfileHelper::AddProfile(Identifier mnId, Identifier mnLinkId, Ipv6Address lmaa, std::list<Ipv6Address> hnps)
+{
+  Pmipv6Profile::Entry *entry;
+  
+  entry = m_profile->Add(mnId);
+  
+  entry->SetMnIdentifier(mnId);
+  entry->SetMnLinkIdentifier(mnLinkId);
+  entry->SetLmaAddress(lmaa);
+  entry->SetHomeNetworkPrefixes(hnps);
+  
+  entry = m_profile->Add(mnLinkId);
+  
+  entry->SetMnIdentifier(mnId);
+  entry->SetMnLinkIdentifier(mnLinkId);
+  entry->SetLmaAddress(lmaa);
+  entry->SetHomeNetworkPrefixes(hnps);
+}
+
+} // namespace ns3
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.h ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/helper/pmip6-helper.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#ifndef PMIP6_HELPER_H
+#define PMIP6_HELPER_H
+
+#include "ns3/node-container.h"
+#include "ns3/net-device-container.h"
+#include "ns3/packet.h"
+#include "ns3/ptr.h"
+#include "ns3/object-factory.h"
+#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/trace-helper.h"
+
+#include "ns3/identifier.h"
+
+namespace ns3 {
+
+class Node;
+class Pmip6ProfileHelper;
+class Pmipv6Profile;
+
+class Pmip6LmaHelper {
+public:
+  Pmip6LmaHelper();
+  ~Pmip6LmaHelper();
+  /**
+   * 
+   * \param node The node on which to install the stack.
+   */
+  void Install (Ptr<Node> node) const;
+  
+  void SetProfileHelper(Pmip6ProfileHelper *pf);
+  
+  void SetPrefixPoolBase(Ipv6Address prefixBegin, uint8_t prefixLen);
+
+protected:
+
+private:
+  Pmip6ProfileHelper *m_profile;
+  
+  Ipv6Address m_prefixBegin;
+  uint8_t m_prefixBeginLen;
+};
+
+class Pmip6MagHelper {
+public:
+  Pmip6MagHelper();
+  ~Pmip6MagHelper();
+  
+  /**
+   * 
+   * \param node The node on which to install the stack.
+   */
+  void Install (Ptr<Node> node) const;
+  void Install (Ptr<Node> node, Ipv6Address target, NodeContainer aps) const;
+  
+  void SetProfileHelper(Pmip6ProfileHelper *pf);
+  
+protected:
+
+private:
+  Pmip6ProfileHelper *m_profile;
+};
+
+class Pmip6ProfileHelper {
+public:
+  Pmip6ProfileHelper();
+  ~Pmip6ProfileHelper();
+  
+  Ptr<Pmipv6Profile> GetProfile();
+  
+  void AddProfile(Identifier mnId, Identifier mnLinkId, Ipv6Address lmaa, std::list<Ipv6Address> hnps);
+protected:
+
+private:
+  Ptr<Pmipv6Profile> m_profile;
+};
+
+} // namespace ns3
+
+#endif /* PMIP6_HELPER_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,611 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/uinteger.h"
+#include "ns3/node.h"
+
+#include "ipv6-mobility-header.h"
+
+#include "ipv6-mobility-option-header.h"
+#include "ipv6-mobility-option.h"
+
+#include "ipv6-mobility-l4-protocol.h"
+
+#include "pmipv6-lma.h"
+
+#include "binding-cache.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("BindingCache");
+
+TypeId BindingCache::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::BindingCache")
+    .SetParent<Object> ()
+    ;
+  return tid;
+} 
+
+BindingCache::BindingCache ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+BindingCache::~BindingCache ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Flush ();
+}
+
+void BindingCache::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Flush ();
+  Object::DoDispose ();
+}
+
+BindingCache::Entry *BindingCache::Lookup(Identifier mnId, std::list<Ipv6Address> hnpList, bool &allMatched)
+{
+  NS_LOG_FUNCTION (this << mnId);
+  
+  if ( m_bCache.find (mnId) == m_bCache.end ())
+    {
+      BindingCache::Entry* entry = m_bCache[mnId];
+	  
+	  BindingCache::Entry* partial = 0;
+	  bool matchtemp;
+	  
+	  while ( entry )
+	    {
+		  matchtemp = false;
+		  if( entry->Match(mnId, hnpList, matchtemp) )
+		    {
+			  if ( matchtemp )
+			    {
+				  allMatched = true;
+				  return entry;
+				}
+			  
+			  if(partial == 0)
+			    {
+			      partial = entry;
+				}
+			}
+		  entry = entry->GetNext();
+		}
+		
+	  allMatched = false;
+	  return partial;
+    }
+  return 0;
+}
+
+BindingCache::Entry *BindingCache::Lookup(Identifier mnId, uint8_t att, Identifier mnLinkId)
+{
+  NS_LOG_FUNCTION (this << mnId << mnLinkId);
+  
+  if ( m_bCache.find (mnId) != m_bCache.end ())
+    {
+      BindingCache::Entry* entry = m_bCache[mnId];
+	  
+	  while ( entry )
+	    {
+		  if( entry->Match(mnId, att, mnLinkId) )
+		    {
+			  return entry;
+			}
+		  entry = entry->GetNext();
+		}
+    }
+  return 0;
+}
+
+BindingCache::Entry *BindingCache::Lookup(Identifier mnId)
+{
+  NS_LOG_FUNCTION (this << mnId );
+  
+  if ( m_bCache.find (mnId) == m_bCache.end ())
+    {
+      BindingCache::Entry* entry = m_bCache[mnId];
+	  
+	  return entry;
+    }
+  return 0;
+}
+
+BindingCache::Entry* BindingCache::Add (Identifier mnId)
+{
+  NS_LOG_FUNCTION (this << mnId );
+  
+  BindingCache::Entry* entry = new BindingCache::Entry (this);
+  
+  entry->SetMnIdentifier(mnId);
+  
+  if( m_bCache.find (mnId) != m_bCache.end ())
+    {
+	  BindingCache::Entry* entry2 = m_bCache[mnId];
+	  
+	  entry->SetNext(entry2);
+	}
+
+  m_bCache[mnId] = entry;
+  
+  return entry;
+}
+
+void BindingCache::Remove (BindingCache::Entry* entry)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (BCacheI i = m_bCache.begin () ; i != m_bCache.end () ; i++)
+    {
+      if ((*i).second == entry)
+        {
+          m_bCache.erase (i);
+          delete entry;
+          return;
+        }
+    }
+}
+
+void BindingCache::Flush ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (BCacheI i = m_bCache.begin () ; i != m_bCache.end () ; i++)
+    {
+      delete (*i).second; /* delete the pointer BindingCache::Entry */
+    }
+
+  m_bCache.erase (m_bCache.begin (), m_bCache.end ());
+}
+
+Ptr<Node> BindingCache::GetNode() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_node;
+}
+
+void BindingCache::SetNode(Ptr<Node> node)
+{
+  NS_LOG_FUNCTION ( this << node );
+  
+  m_node = node;
+}
+
+BindingCache::Entry::Entry (Ptr<BindingCache> bcache)
+  : m_bCache (bcache),
+    m_state (UNREACHABLE),
+    m_tunnelIfIndex (-1),
+    m_reachableTimer(Timer::CANCEL_ON_DESTROY),
+	m_deregisterTimer(Timer::CANCEL_ON_DESTROY),
+	m_registerTimer(Timer::CANCEL_ON_DESTROY),
+    m_next (0),
+	m_tentativeEntry (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+BindingCache::Entry *BindingCache::Entry::Copy()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  Entry *bce = new Entry(this->m_bCache);
+
+  bce->SetMnIdentifier(this->GetMnIdentifier());
+  bce->SetMnLinkIdentifier(this->GetMnLinkIdentifier());
+  bce->SetHomeNetworkPrefixes(this->GetHomeNetworkPrefixes());
+  bce->SetMagLinkAddress(this->GetMagLinkAddress());
+  bce->SetProxyCoa(this->GetProxyCoa());
+  bce->SetTunnelIfIndex(this->GetTunnelIfIndex());
+  bce->SetAccessTechnologyType(this->GetAccessTechnologyType());
+  bce->SetHandoffIndicator(this->GetHandoffIndicator());
+  bce->SetLastBindingUpdateTime(this->GetLastBindingUpdateTime());
+  bce->SetReachableTime(this->GetReachableTime());
+  bce->SetLastBindingUpdateSequence(this->GetLastBindingUpdateSequence());
+  
+  bce->SetNext(0);
+  bce->SetTentativeEntry(0);
+
+  return bce;
+}
+
+bool BindingCache::Entry::IsUnreachable() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+
+  return m_state == UNREACHABLE;  
+}
+
+bool BindingCache::Entry::IsDeregistering() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+
+  return m_state == DEREGISTERING;  
+}
+
+bool BindingCache::Entry::IsRegistering() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+
+  return m_state == REGISTERING;  
+}
+
+bool BindingCache::Entry::IsReachable() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+
+  return m_state == REACHABLE;  
+}
+
+void BindingCache::Entry::MarkUnreachable()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_state = UNREACHABLE;
+}
+
+void BindingCache::Entry::MarkDeregistering()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_state = DEREGISTERING;
+}
+
+void BindingCache::Entry::MarkRegistering ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_state = REGISTERING;
+}
+
+void BindingCache::Entry::MarkReachable()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_state = REACHABLE;
+}
+	
+void BindingCache::Entry::FunctionReachableTimeout()
+{
+  NS_LOG_FUNCTION_NOARGS();
+//  Ptr<Pmipv6Lma> lma = m_bCache->GetNode()->GetObject<Pmipv6Lma>();
+
+}
+
+void BindingCache::Entry::FunctionDeregisterTimeout()
+{
+  NS_LOG_FUNCTION_NOARGS();
+//  Ptr<Pmipv6Lma> lma = m_bCache->GetNode()->GetObject<Pmipv6Lma>();
+
+}
+
+void BindingCache::Entry::FunctionRegisterTimeout()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  Ptr<Pmipv6Lma> lma = m_bCache->GetNode()->GetObject<Pmipv6Lma>();
+
+  NS_LOG_LOGIC ("Timeout waiting for previous MAG's de-reg");
+  
+  lma->DoDelayedRegistration(this);
+}
+
+void BindingCache::Entry::StartReachableTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT ( !m_reachableTime.IsZero() );
+  
+  m_reachableTimer.SetFunction (&BindingCache::Entry::FunctionReachableTimeout, this);
+  m_reachableTimer.SetDelay ( m_reachableTime );
+  m_reachableTimer.Schedule ();
+}
+
+void BindingCache::Entry::StopReachableTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_reachableTimer.Cancel ();
+}
+
+void BindingCache::Entry::StartDeregisterTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_deregisterTimer.SetFunction (&BindingCache::Entry::FunctionDeregisterTimeout, this);
+  m_deregisterTimer.SetDelay ( MilliSeconds (Ipv6MobilityL4Protocol::MIN_DELAY_BEFORE_BCE_DELETE) );
+  m_deregisterTimer.Schedule ();
+}
+
+void BindingCache::Entry::StopDeregisterTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_deregisterTimer.Cancel ();
+}
+
+void BindingCache::Entry::StartRegisterTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_registerTimer.SetFunction (&BindingCache::Entry::FunctionRegisterTimeout, this);
+  m_registerTimer.SetDelay ( MilliSeconds (Ipv6MobilityL4Protocol::MIN_DELAY_BEFORE_NEW_BCE_ASSIGN) );
+  m_registerTimer.Schedule ();
+}
+
+void BindingCache::Entry::StopRegisterTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_registerTimer.Cancel ();
+}
+
+bool BindingCache::Entry::Match(Identifier mnId, std::list<Ipv6Address> hnpList, bool &allMatched) const
+{
+  NS_LOG_FUNCTION ( this << mnId );
+  NS_ASSERT ( mnId == GetMnIdentifier() );
+  
+  if( hnpList.size() == 0 || m_homeNetworkPrefixes.size() == 0 )
+    {
+	  allMatched = false;
+	  
+	  return false;
+	}
+  
+  allMatched = true;
+  
+  bool found = false;
+  bool eachfound;
+  
+  for( std::list<Ipv6Address>::const_iterator i = hnpList.begin(); i != hnpList.end(); i++)
+	{
+	  eachfound = false;
+	  for( std::list<Ipv6Address>::const_iterator j = m_homeNetworkPrefixes.begin(); j != m_homeNetworkPrefixes.end(); j++)
+		{
+		  if( (*i) == (*j) )
+			{
+			  found = true;
+			  eachfound = true;
+			}
+		}
+		
+	  if(eachfound)
+	    {
+		  allMatched = false;
+		}
+	}
+	
+  return found;
+}
+
+bool BindingCache::Entry::Match(Identifier mnId, uint8_t att, Identifier mnLinkId) const
+{
+  NS_LOG_FUNCTION ( this << mnId << (uint32_t) att << mnLinkId );
+  NS_ASSERT ( mnId == GetMnIdentifier() );
+  
+  if( GetAccessTechnologyType() != att )
+    {
+	  return false;
+	}
+	
+  if ( GetMnLinkIdentifier() != mnLinkId )
+    {
+	  return false;
+	}
+
+  return true;
+}
+
+Identifier BindingCache::Entry::GetMnIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_mnIdentifier;
+}
+
+void BindingCache::Entry::SetMnIdentifier(Identifier mnId)
+{
+  NS_LOG_FUNCTION ( this << mnId );
+  
+  m_mnIdentifier = mnId;
+}
+
+Identifier BindingCache::Entry::GetMnLinkIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_mnLinkIdentifier;
+}
+
+void BindingCache::Entry::SetMnLinkIdentifier(Identifier mnLinkId)
+{
+  NS_LOG_FUNCTION ( this << mnLinkId );
+  
+  m_mnLinkIdentifier = mnLinkId;
+}
+
+std::list<Ipv6Address> BindingCache::Entry::GetHomeNetworkPrefixes() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_homeNetworkPrefixes;
+}
+
+void BindingCache::Entry::SetHomeNetworkPrefixes(std::list<Ipv6Address> hnpList)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_homeNetworkPrefixes = hnpList;
+}
+
+Ipv6Address BindingCache::Entry::GetMagLinkAddress() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_magLinkAddress;
+}
+
+void BindingCache::Entry::SetMagLinkAddress(Ipv6Address lla)
+{
+  NS_LOG_FUNCTION ( this << lla );
+  
+  m_magLinkAddress = lla;
+}
+
+Ipv6Address BindingCache::Entry::GetProxyCoa() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_proxyCoa;
+}
+
+void BindingCache::Entry::SetProxyCoa(Ipv6Address pcoa)
+{
+  NS_LOG_FUNCTION ( this << pcoa );
+
+  m_oldProxyCoa = m_proxyCoa;
+  m_proxyCoa = pcoa;
+}
+
+int16_t BindingCache::Entry::GetTunnelIfIndex() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_tunnelIfIndex;
+}
+
+void BindingCache::Entry::SetTunnelIfIndex(int16_t tunnelif)
+{
+  NS_LOG_FUNCTION ( this << tunnelif );
+  
+  m_tunnelIfIndex = tunnelif;
+}
+
+uint8_t BindingCache::Entry::GetAccessTechnologyType() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_accessTechnologyType;
+}
+
+void BindingCache::Entry::SetAccessTechnologyType(uint8_t att)
+{
+  NS_LOG_FUNCTION ( this << (uint32_t) att);
+  
+  m_accessTechnologyType = att;
+}
+
+uint8_t BindingCache::Entry::GetHandoffIndicator() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_handoffIndicator;
+}
+
+void BindingCache::Entry::SetHandoffIndicator(uint8_t hi)
+{
+  NS_LOG_FUNCTION ( this << (uint32_t) hi);
+  
+  m_handoffIndicator = hi;
+}
+
+Time BindingCache::Entry::GetLastBindingUpdateTime() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_lastBindingUpdateTime;
+}
+
+void BindingCache::Entry::SetLastBindingUpdateTime(Time tm)
+{
+  NS_LOG_FUNCTION ( this << tm );
+  
+  m_lastBindingUpdateTime = tm;
+}
+
+Time BindingCache::Entry::GetReachableTime() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_reachableTime;
+}
+
+void BindingCache::Entry::SetReachableTime(Time tm)
+{
+  NS_LOG_FUNCTION (this << tm );
+  
+  m_reachableTime = tm;
+}
+
+uint16_t BindingCache::Entry::GetLastBindingUpdateSequence() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_lastBindingUpdateSequence;
+}
+
+void BindingCache::Entry::SetLastBindingUpdateSequence(uint16_t seq)
+{
+  NS_LOG_FUNCTION( this << seq);
+  
+  m_lastBindingUpdateSequence = seq;
+}
+
+BindingCache::Entry *BindingCache::Entry::GetNext() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_next;
+}
+
+void BindingCache::Entry::SetNext(BindingCache::Entry *entry)
+{
+  NS_LOG_FUNCTION ( this << entry );
+  
+  m_next = entry;
+}
+	
+BindingCache::Entry *BindingCache::Entry::GetTentativeEntry() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_tentativeEntry;
+}
+
+void BindingCache::Entry::SetTentativeEntry(BindingCache::Entry *entry)
+{
+  NS_LOG_FUNCTION ( this << entry );
+  
+  m_tentativeEntry = entry;
+}
+
+Ipv6Address BindingCache::Entry::GetOldProxyCoa() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_oldProxyCoa;
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.h ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-cache.h	2014-01-28 09:53:59.000000000 +0100
@@ -0,0 +1,202 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#ifndef BINDING_CACHE_H
+#define BINDING_CACHE_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ptr.h"
+#include "ns3/timer.h"
+#include "ns3/sgi-hashmap.h"
+#include "ns3/identifier.h"
+
+namespace ns3
+{
+
+class BindingCache : public Object
+{
+public:
+  class Entry;
+  
+  static TypeId GetTypeId ();
+
+  BindingCache();
+  
+  ~BindingCache();
+  
+  BindingCache::Entry *Lookup(Identifier mnId, std::list<Ipv6Address> hnpList, bool &allMatched);
+  BindingCache::Entry *Lookup(Identifier mnId, uint8_t att, Identifier mnLinkId);
+  BindingCache::Entry *Lookup(Identifier mnId);
+  
+  BindingCache::Entry *Add(Identifier mnId);
+  
+  void Remove(BindingCache::Entry *entry);
+  
+  void Flush();
+  
+  Ptr<Node> GetNode() const;
+  void SetNode(Ptr<Node> node);
+  
+  class Entry
+  {
+  public:
+    Entry(Ptr<BindingCache> bcache);
+    
+    Entry *Copy();
+    
+    bool IsUnreachable() const;
+    bool IsDeregistering() const;
+    bool IsRegistering() const;
+    bool IsReachable() const;
+    
+    void MarkUnreachable();
+    void MarkDeregistering();
+    void MarkRegistering();
+    void MarkReachable();
+    
+    void StartReachableTimer();
+    void StopReachableTimer();
+    
+    void StartDeregisterTimer();
+    void StopDeregisterTimer();
+    
+    void StartRegisterTimer();
+    void StopRegisterTimer();
+    
+    void FunctionReachableTimeout();
+    void FunctionDeregisterTimeout();
+    void FunctionRegisterTimeout();
+    
+    bool Match(Identifier mnId, std::list<Ipv6Address> hnpList, bool &allMatched) const;
+    bool Match(Identifier mnId, uint8_t att, Identifier mnLinkId) const;
+    
+    Identifier GetMnIdentifier() const;
+    void SetMnIdentifier(Identifier mnId);
+    
+    Identifier GetMnLinkIdentifier() const;
+    void SetMnLinkIdentifier(Identifier mnLinkId);
+    
+    std::list<Ipv6Address> GetHomeNetworkPrefixes() const;
+    void SetHomeNetworkPrefixes(std::list<Ipv6Address> hnpList);
+    
+    Ipv6Address GetMagLinkAddress() const;
+    void SetMagLinkAddress(Ipv6Address lla);
+    
+    Ipv6Address GetProxyCoa() const;
+    void SetProxyCoa(Ipv6Address pcoa);
+    
+    int16_t GetTunnelIfIndex() const;
+    void SetTunnelIfIndex(int16_t tunnelif);
+    
+    uint8_t GetAccessTechnologyType() const;
+    void SetAccessTechnologyType(uint8_t att);
+    
+    uint8_t GetHandoffIndicator() const;
+    void SetHandoffIndicator(uint8_t hi);
+    
+    Time GetLastBindingUpdateTime() const;
+    void SetLastBindingUpdateTime(Time tm);
+    
+    Time GetReachableTime() const;
+    void SetReachableTime(Time tm);
+    
+    uint16_t GetLastBindingUpdateSequence() const;
+    void SetLastBindingUpdateSequence(uint16_t seq);
+    
+    Entry *GetNext() const;
+    void SetNext(Entry *entry);
+    
+    Entry *GetTentativeEntry() const;
+    void SetTentativeEntry(Entry *entry);
+    
+    Ipv6Address GetOldProxyCoa() const;
+    
+  private:
+    Ptr<BindingCache> m_bCache;
+    
+    enum BindingCacheState_e {
+      UNREACHABLE,
+      DEREGISTERING,
+      REGISTERING,
+      REACHABLE
+    };
+    
+    BindingCacheState_e m_state;
+    
+    Identifier m_mnIdentifier;
+    
+    Identifier m_mnLinkIdentifier;
+    
+    std::list<Ipv6Address> m_homeNetworkPrefixes;
+    
+    Ipv6Address m_magLinkAddress;
+    
+    Ipv6Address m_proxyCoa;
+    
+    int16_t m_tunnelIfIndex;
+    
+    uint8_t m_accessTechnologyType;
+    
+    uint8_t m_handoffIndicator;
+    
+    Time m_lastBindingUpdateTime;
+    uint16_t m_lastBindingUpdateSequence;
+    
+    Time m_reachableTime;
+    Timer m_reachableTimer;
+    Timer m_deregisterTimer;
+    Timer m_registerTimer;
+    
+    Entry *m_next;
+    
+    //internal
+    
+    Entry *m_tentativeEntry;
+    Ipv6Address m_oldProxyCoa;
+
+  };
+  
+protected:
+
+private:
+  typedef sgi::hash_map<Identifier, BindingCache::Entry *, IdentifierHash> BCache;
+  typedef sgi::hash_map<Identifier, BindingCache::Entry *, IdentifierHash>::iterator BCacheI;
+  
+  void DoDispose();
+  
+  BCache m_bCache;
+  
+  Ptr<Node> m_node;
+};
+
+} /* ns3 */
+
+#endif /* BINDING_CACHE_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,603 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/uinteger.h"
+#include "ns3/node.h"
+
+#include "binding-update-list.h"
+
+#include "ipv6-mobility-l4-protocol.h"
+
+#include "ipv6-mobility-header.h"
+
+#include "ipv6-mobility-option-header.h"
+#include "ipv6-mobility-option.h"
+
+#include "pmipv6-mag.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("BindingUpdateList");
+
+TypeId BindingUpdateList::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::BindingUpdateList")
+    .SetParent<Object> ()
+    ;
+  return tid;
+} 
+
+BindingUpdateList::BindingUpdateList ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+BindingUpdateList::~BindingUpdateList ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Flush ();
+}
+
+void BindingUpdateList::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Flush ();
+  Object::DoDispose ();
+}
+
+BindingUpdateList::Entry* BindingUpdateList::Lookup (Identifier mnId)
+{
+  NS_LOG_FUNCTION (this << mnId );
+  
+  if ( m_buList.find (mnId) != m_buList.end ())
+    {
+      BindingUpdateList::Entry* entry = m_buList[mnId];
+      
+      return entry;
+    }
+  return 0;
+}
+
+BindingUpdateList::Entry* BindingUpdateList::Add (Identifier mnId)
+{
+  NS_LOG_FUNCTION (this << mnId );
+  NS_ASSERT( Lookup(mnId) == 0 );
+  
+  BindingUpdateList::Entry* entry = new BindingUpdateList::Entry (this);
+  
+  entry->SetMnIdentifier(mnId);
+  
+  if( m_buList.find (mnId) != m_buList.end ())
+    {
+      BindingUpdateList::Entry* entry2 = m_buList[mnId];
+      
+      entry->SetNext(entry2);
+    }
+
+  m_buList[mnId] = entry;
+  
+  return entry;
+}
+
+void BindingUpdateList::Remove (BindingUpdateList::Entry* entry)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (BUListI i = m_buList.begin () ; i != m_buList.end () ; i++)
+    {
+      if ((*i).second != entry)
+        {
+          m_buList.erase (i);
+          delete entry;
+          return;
+        }
+    }
+}
+
+void BindingUpdateList::Flush ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (BUListI i = m_buList.begin () ; i != m_buList.end () ; i++)
+    {
+      delete (*i).second; /* delete the pointer BindingUpdateList::Entry */
+    }
+
+  m_buList.erase (m_buList.begin (), m_buList.end ());
+}
+
+Ptr<Node> BindingUpdateList::GetNode() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_node;
+}
+
+void BindingUpdateList::SetNode(Ptr<Node> node)
+{
+  NS_LOG_FUNCTION ( this << node );
+  
+  m_node = node;
+}
+
+BindingUpdateList::Entry::Entry (Ptr<BindingUpdateList> bul)
+  : m_buList (bul),
+  m_state (UNREACHABLE),
+  m_ifIndex(-1),
+  m_tunnelIfIndex(-1),
+  m_retransTimer (Timer::CANCEL_ON_DESTROY),
+  m_reachableTimer (Timer::CANCEL_ON_DESTROY),
+  m_refreshTimer (Timer::CANCEL_ON_DESTROY),
+  m_radvdIfIndex (-1),
+  m_next (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void BindingUpdateList::Entry::FunctionRefreshTimeout ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<Pmipv6Mag> mag = m_buList->GetNode ()->GetObject<Pmipv6Mag> ();
+   
+  if (mag == 0)
+    {
+      NS_LOG_WARN("No MAG agent for Binding Update List");
+      
+      return;
+    }
+    
+  SetLastBindingUpdateTime (MicroSeconds (Simulator::Now ().GetMicroSeconds ()));
+  SetLastBindingUpdateSequence (mag->GetSequence ());
+ 
+  Ptr<Packet> p = mag->BuildPbu(this);
+  
+  SetPbuPacket(p);
+  
+  ResetRetryCount();
+  
+  mag->SendMessage(p->Copy(), GetLmaAddress(), 64);
+  
+  MarkRefreshing();
+  
+  StartRetransTimer();
+}
+
+void BindingUpdateList::Entry::FunctionReachableTimeout()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  Ptr<Pmipv6Mag> mag = m_buList->GetNode()->GetObject<Pmipv6Mag>();
+  
+  NS_LOG_LOGIC ("Reachable Timeout");
+   
+  if( mag == 0)
+    {
+      NS_LOG_WARN("No MAG agent for Binding Update List");
+      
+      return;
+    }
+    
+  if(IsReachable())
+    {
+      MarkUnreachable();
+    }
+  else if(IsRefreshing())
+    {
+      MarkUpdating();
+    }
+
+  if( m_radvdIfIndex >= 0 )
+    {
+      mag->ClearRadvdInterface (this);
+    }
+      
+  //delete routing && tunnel
+  if (m_tunnelIfIndex >= 0)
+    {
+      mag->ClearTunnelAndRouting (this);
+    }
+}
+
+void BindingUpdateList::Entry::FunctionRetransTimeout()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  Ptr<Pmipv6Mag> mag = m_buList->GetNode()->GetObject<Pmipv6Mag>();
+  
+  if( mag == 0)
+    {
+      NS_LOG_WARN("No MAG agent for Binding Update List");
+      
+      return;
+    }
+  
+  IncreaseRetryCount();
+  
+  if ( GetRetryCount() > Ipv6MobilityL4Protocol::MAX_BINDING_UPDATE_RETRY_COUNT )
+    {
+      NS_LOG_LOGIC ("Maximum retry count reached. Giving up..");
+      
+      return;
+    }
+  
+  mag->SendMessage(GetPbuPacket ()->Copy (), GetLmaAddress (), 64);
+  
+  StartRetransTimer();  
+}
+
+bool BindingUpdateList::Entry::IsUnreachable() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_state == UNREACHABLE;
+}
+
+bool BindingUpdateList::Entry::IsUpdating() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_state == UPDATING;
+}
+
+bool BindingUpdateList::Entry::IsRefreshing() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_state == REFRESHING;
+}
+
+bool BindingUpdateList::Entry::IsReachable() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_state == REACHABLE;
+}
+
+void BindingUpdateList::Entry::MarkUnreachable()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  m_state = UNREACHABLE;
+}
+
+void BindingUpdateList::Entry::MarkUpdating()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  m_state = UPDATING;
+}
+
+void BindingUpdateList::Entry::MarkRefreshing()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  m_state = REFRESHING;
+}
+
+void BindingUpdateList::Entry::MarkReachable()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  m_state = REACHABLE;
+}
+    
+void BindingUpdateList::Entry::StartReachableTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT ( !m_reachableTime.IsZero() );
+  
+  m_reachableTimer.SetFunction (&BindingUpdateList::Entry::FunctionReachableTimeout, this);
+  m_reachableTimer.SetDelay ( Seconds (m_reachableTime.GetSeconds ()));
+  m_reachableTimer.Schedule ();
+}
+
+void BindingUpdateList::Entry::StopReachableTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_reachableTimer.Cancel ();
+}
+
+void BindingUpdateList::Entry::StartRetransTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_retransTimer.SetFunction (&BindingUpdateList::Entry::FunctionRetransTimeout, this);
+  
+  if (GetRetryCount () == 0)
+    {
+      m_retransTimer.SetDelay (Seconds (Ipv6MobilityL4Protocol::INITIAL_BINDING_ACK_TIMEOUT_FIRSTREG));
+    }
+  else
+    {
+      m_retransTimer.SetDelay (Seconds (Ipv6MobilityL4Protocol::INITIAL_BINDING_ACK_TIMEOUT_REREG));
+    }
+    
+  m_retransTimer.Schedule ();
+}
+
+void BindingUpdateList::Entry::StopRetransTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_retransTimer.Cancel ();
+}
+
+void BindingUpdateList::Entry::StartRefreshTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  NS_ASSERT ( !m_reachableTime.IsZero() );
+  
+  m_refreshTimer.SetFunction (&BindingUpdateList::Entry::FunctionRefreshTimeout, this);
+  m_refreshTimer.SetDelay ( Seconds ( m_reachableTime.GetSeconds() * 0.9 ) );
+  m_refreshTimer.Schedule ();
+}
+
+void BindingUpdateList::Entry::StopRefreshTimer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_refreshTimer.Cancel ();
+}
+
+bool BindingUpdateList::Entry::Match(Identifier mnId) const
+{
+  NS_LOG_FUNCTION ( this << mnId );
+  NS_ASSERT ( mnId == GetMnIdentifier() );
+
+  return true;
+}
+
+Identifier BindingUpdateList::Entry::GetMnIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_mnIdentifier;
+}
+
+void BindingUpdateList::Entry::SetMnIdentifier(Identifier mnId)
+{
+  NS_LOG_FUNCTION ( this << mnId );
+  
+  m_mnIdentifier = mnId;
+}
+
+Identifier BindingUpdateList::Entry::GetMnLinkIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_mnLinkIdentifier;
+}
+
+void BindingUpdateList::Entry::SetMnLinkIdentifier(Identifier mnLinkId)
+{
+  NS_LOG_FUNCTION ( this << mnLinkId );
+  
+  m_mnLinkIdentifier = mnLinkId;
+}
+
+std::list<Ipv6Address> BindingUpdateList::Entry::GetHomeNetworkPrefixes() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_homeNetworkPrefixes;
+}
+
+void BindingUpdateList::Entry::SetHomeNetworkPrefixes(std::list<Ipv6Address> hnpList)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_homeNetworkPrefixes = hnpList;
+}
+
+Ipv6Address BindingUpdateList::Entry::GetMagLinkAddress() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_magLinkAddress;
+}
+
+void BindingUpdateList::Entry::SetMagLinkAddress(Ipv6Address lla)
+{
+  NS_LOG_FUNCTION ( this << lla );
+  
+  m_magLinkAddress = lla;
+}
+
+Ipv6Address BindingUpdateList::Entry::GetLmaAddress() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_lmaAddress;
+}
+
+void BindingUpdateList::Entry::SetLmaAddress(Ipv6Address lmaa)
+{
+  NS_LOG_FUNCTION ( this << lmaa );
+  
+  m_lmaAddress = lmaa;
+}
+
+int16_t BindingUpdateList::Entry::GetIfIndex() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_ifIndex;
+}
+
+void BindingUpdateList::Entry::SetIfIndex(int16_t ifi)
+{
+  NS_LOG_FUNCTION ( this << ifi );
+  
+  m_ifIndex = ifi;
+}
+
+int16_t BindingUpdateList::Entry::GetTunnelIfIndex() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_tunnelIfIndex;
+}
+
+void BindingUpdateList::Entry::SetTunnelIfIndex(int16_t tunnelif)
+{
+  NS_LOG_FUNCTION ( this << tunnelif );
+  
+  m_tunnelIfIndex = tunnelif;
+}
+
+uint8_t BindingUpdateList::Entry::GetAccessTechnologyType() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_accessTechnologyType;
+}
+
+void BindingUpdateList::Entry::SetAccessTechnologyType(uint8_t att)
+{
+  NS_LOG_FUNCTION ( this << (uint32_t) att);
+  
+  m_accessTechnologyType = att;
+}
+
+uint8_t BindingUpdateList::Entry::GetHandoffIndicator() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_handoffIndicator;
+}
+
+void BindingUpdateList::Entry::SetHandoffIndicator(uint8_t hi)
+{
+  NS_LOG_FUNCTION ( this << (uint32_t) hi);
+  
+  m_handoffIndicator = hi;
+}
+
+Time BindingUpdateList::Entry::GetLastBindingUpdateTime() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_lastBindingUpdateTime;
+}
+
+void BindingUpdateList::Entry::SetLastBindingUpdateTime(Time tm)
+{
+  NS_LOG_FUNCTION ( this << tm );
+  
+  m_lastBindingUpdateTime = tm;
+}
+
+Time BindingUpdateList::Entry::GetReachableTime() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_reachableTime;
+}
+
+void BindingUpdateList::Entry::SetReachableTime(Time tm)
+{
+  NS_LOG_FUNCTION (this << tm );
+  
+  m_reachableTime = tm;
+}
+
+uint16_t BindingUpdateList::Entry::GetLastBindingUpdateSequence() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_lastBindingUpdateSequence;
+}
+
+void BindingUpdateList::Entry::SetLastBindingUpdateSequence(uint16_t seq)
+{
+  NS_LOG_FUNCTION( this << seq);
+  
+  m_lastBindingUpdateSequence = seq;
+}
+
+Ptr<Packet> BindingUpdateList::Entry::GetPbuPacket() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_pktPbu;
+}
+
+void BindingUpdateList::Entry::SetPbuPacket(Ptr<Packet> pkt)
+{
+  NS_LOG_FUNCTION( this << pkt );
+  
+  m_pktPbu = pkt;
+}
+
+uint8_t BindingUpdateList::Entry::GetRetryCount() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_retryCount;
+}
+
+void BindingUpdateList::Entry::ResetRetryCount()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  m_retryCount = 0;
+}
+
+void BindingUpdateList::Entry::IncreaseRetryCount()
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  m_retryCount++;
+}
+
+BindingUpdateList::Entry *BindingUpdateList::Entry::GetNext() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_next;
+}
+
+void BindingUpdateList::Entry::SetNext(BindingUpdateList::Entry *entry)
+{
+  NS_LOG_FUNCTION ( this << entry );
+  
+  m_next = entry;
+}
+
+int32_t BindingUpdateList::Entry::GetRadvdIfIndex() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_radvdIfIndex;
+}
+
+void BindingUpdateList::Entry::SetRadvdIfIndex(int32_t ifIndex)
+{
+  NS_LOG_FUNCTION ( this << ifIndex );
+  
+  m_radvdIfIndex = ifIndex;
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.h ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/binding-update-list.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,213 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#ifndef BINDING_UPDATE_LIST_H
+#define BINDING_UPDATE_LIST_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ptr.h"
+#include "ns3/timer.h"
+#include "ns3/sgi-hashmap.h"
+
+#include "identifier.h"
+
+namespace ns3
+{
+
+class BindingUpdateList : public Object
+{
+public:
+  class Entry;
+  
+  static TypeId GetTypeId ();
+
+  BindingUpdateList();
+  
+  ~BindingUpdateList();
+  
+  BindingUpdateList::Entry *Lookup(Identifier mnId);
+  
+  BindingUpdateList::Entry *Add(Identifier mnId);
+  
+  void Remove(BindingUpdateList::Entry *entry);
+  
+  void Flush();
+  
+  Ptr<Node> GetNode() const;
+  void SetNode(Ptr<Node> node);
+  
+  class Entry
+  {
+  public:
+    Entry(Ptr<BindingUpdateList> bul);
+	
+	bool IsUnreachable() const;
+	bool IsUpdating() const;
+	bool IsRefreshing() const;
+	bool IsReachable() const;
+	
+	void MarkUnreachable();
+	void MarkUpdating();
+	void MarkRefreshing();
+	void MarkReachable();
+	
+	//timer processing
+	void StartRetransTimer();
+	void StopRetransTimer();
+	
+	void StartReachableTimer();
+	void StopReachableTimer();
+	
+	void StartRefreshTimer();
+	void StopRefreshTimer();
+	
+	void FunctionRetransTimeout();
+	void FunctionReachableTimeout();
+	void FunctionRefreshTimeout();
+	
+	bool Match(Identifier mnId) const;
+	
+	Identifier GetMnIdentifier() const;
+	void SetMnIdentifier(Identifier mnId);
+	
+	Identifier GetMnLinkIdentifier() const;
+	void SetMnLinkIdentifier(Identifier mnLinkId);
+	
+	std::list<Ipv6Address> GetHomeNetworkPrefixes() const;
+	void SetHomeNetworkPrefixes(std::list<Ipv6Address> hnpList);
+	
+	Ipv6Address GetMagLinkAddress() const;
+	void SetMagLinkAddress(Ipv6Address lla);
+	
+	Ipv6Address GetLmaAddress() const;
+	void SetLmaAddress(Ipv6Address lmaa);
+	
+	int16_t GetIfIndex() const;
+	void SetIfIndex(int16_t ifi);
+	
+	int16_t GetTunnelIfIndex() const;
+	void SetTunnelIfIndex(int16_t tunnelif);
+	
+	uint8_t GetAccessTechnologyType() const;
+	void SetAccessTechnologyType(uint8_t att);
+	
+	uint8_t GetHandoffIndicator() const;
+	void SetHandoffIndicator(uint8_t hi);
+	
+	Time GetLastBindingUpdateTime() const;
+	void SetLastBindingUpdateTime(Time tm);
+	
+	Time GetReachableTime() const;
+	void SetReachableTime(Time tm);
+	
+	uint16_t GetLastBindingUpdateSequence() const;
+	void SetLastBindingUpdateSequence(uint16_t seq);
+	
+	Ptr<Packet> GetPbuPacket() const;
+	void SetPbuPacket(Ptr<Packet> pkt);
+	
+	uint8_t GetRetryCount() const;
+	void IncreaseRetryCount();
+	void ResetRetryCount();
+	
+	Entry *GetNext() const;
+	void SetNext(Entry *entry);
+	
+	int32_t GetRadvdIfIndex() const;
+	void SetRadvdIfIndex(int32_t ifIndex);
+	
+  private:
+	enum BindingUpdateState_e {
+      UNREACHABLE,
+	  UPDATING,
+	  REFRESHING,
+	  REACHABLE,
+	};
+
+    Ptr<BindingUpdateList> m_buList;
+	
+	BindingUpdateState_e m_state;
+	
+    Identifier m_mnIdentifier;
+	
+	Identifier m_mnLinkIdentifier;
+	
+	std::list<Ipv6Address> m_homeNetworkPrefixes;
+	
+	Ipv6Address m_magLinkAddress;
+	
+	Ipv6Address m_lmaAddress;
+	
+	int16_t m_ifIndex;
+	
+	int16_t m_tunnelIfIndex;
+	
+	uint8_t m_accessTechnologyType;
+	
+	uint8_t m_handoffIndicator;
+	
+	Time m_lastBindingUpdateTime;
+	
+	Time m_reachableTime;
+	
+	Timer m_retransTimer;
+	
+	Timer m_reachableTimer;
+	
+	Timer m_refreshTimer;
+	
+	uint16_t m_lastBindingUpdateSequence;
+	Ptr<Packet> m_pktPbu;
+	
+	uint8_t m_retryCount;
+	
+	//internal
+	int32_t m_radvdIfIndex; //Radvd Interface Index
+	
+	Entry *m_next;
+  };
+  
+protected:
+
+private:
+  typedef sgi::hash_map<Identifier, BindingUpdateList::Entry *, IdentifierHash> BUList;
+  typedef sgi::hash_map<Identifier, BindingUpdateList::Entry *, IdentifierHash>::iterator BUListI;
+  
+  void DoDispose();
+  
+  BUList m_buList;
+  
+  Ptr<Node> m_node;
+};
+
+} /* ns3 */
+
+#endif /* BINDING_UPDATE_LIST_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,219 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/mac48-address.h"
+
+#include <iomanip>
+
+#include "identifier.h"
+
+namespace ns3 {
+
+Identifier::Identifier()
+  : m_len(0)
+{
+  memset (m_identifier, 0, MAX_SIZE);
+}
+
+Identifier::Identifier(const uint8_t *identifier, uint8_t len)
+  : m_len(len)
+{
+  memcpy(m_identifier, identifier, m_len);
+}
+
+Identifier::Identifier(const char *str)
+{
+  m_len = strlen(str);
+  memcpy(m_identifier, str, m_len);
+}
+
+Identifier::Identifier(Mac48Address addr)
+ : m_len(6)
+{
+  addr.CopyTo(m_identifier);
+}
+
+Identifier::Identifier(const Identifier &identifier)
+  : m_len(identifier.m_len)
+{
+  memcpy(m_identifier, identifier.m_identifier, m_len);
+}
+
+Identifier &
+Identifier::operator = (const Identifier &identifier)
+{
+  m_len = identifier.m_len;
+  memcpy(m_identifier, identifier.m_identifier, m_len);
+  return *this;
+}
+
+uint8_t
+Identifier::GetLength (void) const
+{
+  return m_len;
+}
+
+uint32_t
+Identifier::CopyTo (uint8_t *buffer, uint8_t len) const
+{
+  NS_ASSERT (len >= m_len);
+  
+  memcpy (buffer, m_identifier, m_len);
+  return m_len;
+}
+
+uint32_t
+Identifier::CopyFrom (const uint8_t *buffer, uint8_t len)
+{
+  memcpy (m_identifier, buffer, len);
+  m_len = len;
+  
+  return m_len;
+}
+
+bool Identifier::IsEmpty () const
+{
+  return (m_len == 0);
+}
+
+bool operator == (const Identifier &a, const Identifier &b)
+{
+  if(a.m_len != b.m_len)
+    {
+	  return false;
+	}
+  return memcmp (a.m_identifier, b.m_identifier, a.m_len) == 0;
+}
+
+bool operator != (const Identifier &a, const Identifier &b)
+{
+  return !(a == b);
+}
+
+std::ostream& operator<< (std::ostream& os, const Identifier & identifier)
+{
+  os.setf (std::ios::hex, std::ios::basefield);
+  os.fill('0');
+  for (uint8_t i = 0; i < (identifier.m_len-1); ++i)
+    {
+	  os << std::setw(2) << (uint32_t)identifier.m_identifier[i] << ":";
+	}
+  os << std::setw(2) << (uint32_t)identifier.m_identifier[identifier.m_len-1];
+  os.setf (std::ios::dec, std::ios::basefield);
+  os.fill(' ');
+  return os;
+}
+
+
+#ifdef __cplusplus
+extern "C"
+{ /* } */
+#endif
+
+/**
+ * \brief Get a hash key.
+ * \param k the key
+ * \param length the length of the key
+ * \param level the previous hash, or an arbitrary value
+ * \return hash
+ * \note Adapted from Jens Jakobsen implementation (chillispot).
+ */
+static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level)
+{
+#define mix(a, b, c) \
+  ({ \
+   (a) -= (b); (a) -= (c); (a) ^= ((c) >> 13); \
+   (b) -= (c); (b) -= (a); (b) ^= ((a) << 8);  \
+   (c) -= (a); (c) -= (b); (c) ^= ((b) >> 13); \
+   (a) -= (b); (a) -= (c); (a) ^= ((c) >> 12); \
+   (b) -= (c); (b) -= (a); (b) ^= ((a) << 16); \
+   (c) -= (a); (c) -= (b); (c) ^= ((b) >> 5);  \
+   (a) -= (b); (a) -= (c); (a) ^= ((c) >> 3);  \
+   (b) -= (c); (b) -= (a); (b) ^= ((a) << 10); \
+   (c) -= (a); (c) -= (b); (c) ^= ((b) >> 15); \
+   })
+
+  typedef uint32_t  ub4;   /* unsigned 4-byte quantities */
+  typedef unsigned  char ub1;   /* unsigned 1-byte quantities */
+  uint32_t a = 0;
+  uint32_t b = 0;
+  uint32_t c = 0;
+  uint32_t len = 0;
+
+  /* Set up the internal state */
+  len = length;
+  a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
+  c = level;           /* the previous hash value */
+
+  /* handle most of the key */
+  while (len >= 12)
+    {
+      a += (k[0] + ((ub4)k[1] << 8) + ((ub4)k[2] << 16) + ((ub4)k[3] << 24));
+      b += (k[4] + ((ub4)k[5] << 8) + ((ub4)k[6] << 16) + ((ub4)k[7] << 24));
+      c += (k[8] + ((ub4)k[9] << 8) + ((ub4)k[10] << 16) + ((ub4)k[11] << 24));
+      mix (a, b, c);
+      k += 12; 
+      len -= 12;
+    }
+
+  /* handle the last 11 bytes */
+  c += length;
+  switch (len) /* all the case statements fall through */
+    {
+    case 11: c += ((ub4)k[10] << 24);
+    case 10: c += ((ub4)k[9] << 16);
+    case 9 : c += ((ub4)k[8] << 8); /* the first byte of c is reserved for the length */
+    case 8 : b += ((ub4)k[7] << 24);
+    case 7 : b += ((ub4)k[6] << 16);
+    case 6 : b += ((ub4)k[5] << 8);
+    case 5 : b += k[4];
+    case 4 : a += ((ub4)k[3] << 24);
+    case 3 : a += ((ub4)k[2] << 16);
+    case 2 : a += ((ub4)k[1] << 8);
+    case 1 : a += k[0];
+             /* case 0: nothing left to add */
+    }
+  mix (a, b, c);
+
+#undef mix
+
+  /* report the result */
+  return c;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+size_t IdentifierHash::operator () (Identifier const &x) const
+{
+  uint8_t buf[Identifier::MAX_SIZE];
+
+  x.CopyTo (buf, Identifier::MAX_SIZE);
+
+  return lookuphash (buf, x.GetLength(), 0);
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.h ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/identifier.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,99 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+ 
+#ifndef IDENTIFIER_H
+#define IDENTIFIER_H
+
+#include <stdint.h>
+#include <string.h>
+
+#include <ostream>
+
+#include "ns3/attribute-helper.h"
+
+namespace ns3
+{
+
+class Mac48Address;
+
+/**
+ * \class Identifier
+ * \brief Identifier.
+ */
+class Identifier
+{
+public:
+  enum MaxSize_e {
+    MAX_SIZE = 255
+  };
+  
+  Identifier();
+  Identifier(const uint8_t *buffer, uint8_t len);
+  Identifier(const char *str);
+  Identifier(Mac48Address addr);
+  Identifier(const Identifier & identifier);
+  Identifier &operator = (const Identifier &identifier);
+  
+  uint8_t GetLength (void) const;
+  
+  uint32_t CopyTo (uint8_t *buffer, uint8_t len) const;
+  
+  uint32_t CopyFrom (const uint8_t *buffer, uint8_t len);
+  
+  bool IsEmpty() const;
+
+protected:
+
+private:
+  friend bool operator == (const Identifier &a, const Identifier &b);
+  friend bool operator != (const Identifier &a, const Identifier &b);
+  friend std::ostream& operator<< (std::ostream& os, const Identifier & identifier);
+  
+  uint8_t m_len;
+  uint8_t m_identifier[MAX_SIZE];
+};
+
+ATTRIBUTE_HELPER_HEADER (Identifier);
+
+bool operator == (const Identifier &a, const Identifier &b);
+bool operator != (const Identifier &a, const Identifier &b);
+std::ostream& operator<< (std::ostream& os, const Identifier & identifier);
+
+/**
+ * \class IdentifierHash
+ * \brief Hash function class for Identifier.
+ */
+class IdentifierHash : public std::unary_function<Identifier, size_t>
+{
+public:
+  /**
+   * \brief Unary operator to hash Identifier.
+   * \param x Identifier to hash
+   */
+  size_t operator () (Identifier const &x) const;
+};
+
+} /* namespace ns3 */
+
+#endif /* MOBILITY_HEADER_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,97 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#include "ns3/log.h"
+#include "ns3/object-vector.h"
+
+#include "ipv6-mobility-demux.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityDemux);
+
+TypeId Ipv6MobilityDemux::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityDemux")
+    .SetParent<Object> ()
+    .AddAttribute ("Mobilities", "The set of IPv6 Mobilities registered with this demux.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Ipv6MobilityDemux::m_mobilities),
+                   MakeObjectVectorChecker<Ipv6Mobility> ())
+    ;
+  return tid;
+}
+
+Ipv6MobilityDemux::Ipv6MobilityDemux ()
+{
+}
+
+Ipv6MobilityDemux::~Ipv6MobilityDemux ()
+{
+}
+
+void Ipv6MobilityDemux::DoDispose ()
+{
+  for (Ipv6MobilityList_t::iterator it = m_mobilities.begin (); it != m_mobilities.end (); it++)
+    {
+      (*it)->Dispose ();
+      *it = 0;
+    }
+  m_mobilities.clear ();
+  m_node = 0;
+  Object::DoDispose ();
+}
+
+void Ipv6MobilityDemux::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+void Ipv6MobilityDemux::Insert (Ptr<Ipv6Mobility> mobility)
+{
+  m_mobilities.push_back (mobility);
+}
+
+Ptr<Ipv6Mobility> Ipv6MobilityDemux::GetMobility (int mobilityNumber)
+{
+  for (Ipv6MobilityList_t::iterator i = m_mobilities.begin (); i != m_mobilities.end (); ++i)
+    {
+      if ((*i)->GetMobilityNumber () == mobilityNumber)
+        {
+          return *i;
+        }
+    }
+  return 0;
+}
+
+void Ipv6MobilityDemux::Remove (Ptr<Ipv6Mobility> mobility)
+{
+  m_mobilities.remove (mobility);
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-demux.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,110 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_MOBILITY_DEMUX_H
+#define IPV6_MOBILITY_DEMUX_H
+
+#include <list>
+
+#include "ns3/header.h"
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
+namespace ns3
+{
+
+class Ipv6Mobility;
+class Node;
+
+/**
+ * \class Ipv6MobilityDemux
+ * \brief Ipv6 Mobility Demux.
+ */
+class Ipv6MobilityDemux : public Object
+{
+public:
+  /**
+   * \brief The interface ID.
+   * \return type ID
+   */
+  static TypeId GetTypeId (void);
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MobilityDemux ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityDemux ();
+
+  /**
+   * \brief Set the node.
+   * \param node the node to set
+   */
+  void SetNode (Ptr<Node> node);
+
+  /**
+   * \brief Insert a new IPv6 Mobility.
+   * \param option the option to insert
+   */
+  void Insert (Ptr<Ipv6Mobility> mobility);
+
+  /**
+   * \brief Get the mobility corresponding to mobilityNumber.
+   * \param mobilityNumber the mobility number of the option to retrieve
+   * \return a matching IPv6 Mobility mobility
+   */
+  Ptr<Ipv6Mobility> GetMobility (int mobilityNumber);
+
+  /**
+   * \brief Remove an mobility from this demux.
+   * \param mobility pointer on the mobility to remove
+   */
+  void Remove (Ptr<Ipv6Mobility> mobility);
+
+protected:
+  /**
+   * \brief Dispose this object.
+   */
+  virtual void DoDispose();
+
+private:
+  typedef std::list<Ptr<Ipv6Mobility> > Ipv6MobilityList_t;
+
+  /**
+   * \brief List of IPv6 Mobility supported.
+   */
+  Ipv6MobilityList_t m_mobilities;
+
+  /**
+   * \brief The node.
+   */
+  Ptr<Node> m_node;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_MOBILITY_DEMUX_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,687 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#include "ns3/log.h"
+
+#include "identifier.h"
+#include "ipv6-mobility-header.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityHeader);
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6MobilityHeader");
+
+TypeId Ipv6MobilityHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityHeader")
+    .SetParent<Header> ()
+    .AddConstructor<Ipv6MobilityHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityHeader::Ipv6MobilityHeader ()
+  : m_payload_proto(59),
+  m_header_len(0),
+  m_mh_type(0),
+  m_reserved(0),
+  m_checksum(0)
+{
+}
+
+Ipv6MobilityHeader::~Ipv6MobilityHeader ()
+{
+}
+
+uint8_t Ipv6MobilityHeader::GetPayloadProto () const
+{
+  return m_payload_proto;
+}
+
+void Ipv6MobilityHeader::SetPayloadProto (uint8_t payload_proto)
+{
+  m_payload_proto = payload_proto;
+}
+
+uint8_t Ipv6MobilityHeader::GetHeaderLen () const
+{
+  return m_header_len;
+}
+
+void Ipv6MobilityHeader::SetHeaderLen (uint8_t header_len)
+{
+  m_header_len = header_len;
+}
+
+uint8_t Ipv6MobilityHeader::GetMhType () const
+{
+  return m_mh_type;
+}
+
+void Ipv6MobilityHeader::SetMhType (uint8_t mh_type)
+{
+  m_mh_type = mh_type;
+}
+
+uint8_t Ipv6MobilityHeader::GetReserved () const
+{
+  return m_reserved;
+}
+
+void Ipv6MobilityHeader::SetReserved (uint8_t reserved)
+{
+  m_reserved = reserved;
+}
+
+uint16_t Ipv6MobilityHeader::GetChecksum () const
+{
+  return m_checksum;
+}
+
+void Ipv6MobilityHeader::SetChecksum (uint16_t checksum)
+{
+  m_checksum = checksum;
+}
+
+void Ipv6MobilityHeader::Print (std::ostream& os) const
+{
+  os << "( payload_proto = " << (uint32_t)GetPayloadProto() << " header_len = " << (uint32_t)GetHeaderLen() << " mh_type = " << (uint32_t)GetMhType() << " checksum = " << (uint32_t)GetChecksum() <<")";
+}
+
+uint32_t Ipv6MobilityHeader::GetSerializedSize () const
+{
+  return 6;
+}
+
+uint32_t Ipv6MobilityHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+
+  m_payload_proto = i.ReadU8();
+  m_header_len = i.ReadU8();
+  m_mh_type = i.ReadU8();
+  m_reserved = i.ReadU8();
+  m_checksum = i.ReadNtohU16();
+
+  return GetSerializedSize ();
+}
+
+void Ipv6MobilityHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+
+  i.WriteU8 (m_payload_proto);
+  i.WriteU8 (m_header_len);
+  i.WriteU8 (m_mh_type);
+  i.WriteU8 (m_reserved);
+  i.WriteU16 (0);
+}
+
+MobilityOptionField::MobilityOptionField (uint32_t optionsOffset)
+  : m_optionData (0),
+  m_optionsOffset (optionsOffset)
+{
+}
+
+MobilityOptionField::~MobilityOptionField ()
+{
+}
+
+uint32_t MobilityOptionField::GetSerializedSize () const
+{
+  return m_optionData.GetSize () + CalculatePad ((Ipv6MobilityOptionHeader::Alignment) {8,0});
+}
+
+void MobilityOptionField::Serialize (Buffer::Iterator start) const
+{
+  start.Write (m_optionData.Begin (), m_optionData.End ());
+  uint32_t fill = CalculatePad ((Ipv6MobilityOptionHeader::Alignment) {8,0});
+  
+  NS_LOG_LOGIC ("fill with " << fill << " bytes padding");
+  switch (fill)
+    {
+    case 0: return;
+    case 1: Ipv6MobilityOptionPad1Header ().Serialize (start);
+            return;
+    default: Ipv6MobilityOptionPadnHeader (fill).Serialize (start);
+             return;
+    }
+}
+
+uint32_t MobilityOptionField::Deserialize (Buffer::Iterator start, uint32_t length)
+{
+  uint8_t buf[length];
+  start.Read (buf, length);
+  m_optionData = Buffer ();
+  m_optionData.AddAtEnd (length);
+  m_optionData.Begin ().Write (buf, length);
+  return length;
+}
+
+void MobilityOptionField::AddOption (Ipv6MobilityOptionHeader const& option)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  uint32_t pad = CalculatePad (option.GetAlignment ());
+  
+  NS_LOG_LOGIC ("need " << pad << " bytes padding");
+  switch (pad)
+    {
+    case 0: break; //no padding needed
+    case 1: AddOption (Ipv6MobilityOptionPad1Header ());
+            break;
+    default: AddOption (Ipv6MobilityOptionPadnHeader (pad));
+             break;
+    }
+
+  m_optionData.AddAtEnd (option.GetSerializedSize ());
+  Buffer::Iterator it = m_optionData.End ();
+  it.Prev (option.GetSerializedSize ());
+  option.Serialize (it);
+}
+
+uint32_t MobilityOptionField::CalculatePad (Ipv6MobilityOptionHeader::Alignment alignment) const
+{
+  return (alignment.offset - (m_optionData.GetSize () + m_optionsOffset)) % alignment.factor;
+}
+
+uint32_t MobilityOptionField::GetOptionsOffset ()
+{
+  return m_optionsOffset;
+}
+
+Buffer MobilityOptionField::GetOptionBuffer ()
+{
+  return m_optionData;
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityBindingUpdateHeader);
+
+TypeId Ipv6MobilityBindingUpdateHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityBindingUpdateHeader")
+    .SetParent<Ipv6MobilityHeader> ()
+    .AddConstructor<Ipv6MobilityBindingUpdateHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityBindingUpdateHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityBindingUpdateHeader::Ipv6MobilityBindingUpdateHeader ()
+: MobilityOptionField(12)
+{
+  SetHeaderLen(0);
+  SetMhType(IPV6_MOBILITY_BINDING_UPDATE);
+  SetReserved(0);
+  SetChecksum(0);
+  
+  SetSequence(0);
+  SetFlagA(0);
+  SetFlagH(0);
+  SetFlagL(0);
+  SetFlagK(0);
+  SetFlagM(0);
+  SetFlagR(0);
+  SetFlagP(0);
+  SetReserved2(0);
+  SetLifetime(0);
+}
+
+Ipv6MobilityBindingUpdateHeader::~Ipv6MobilityBindingUpdateHeader ()
+{
+}
+
+uint16_t Ipv6MobilityBindingUpdateHeader::GetSequence () const
+{
+  return m_sequence;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetSequence (uint16_t sequence)
+{
+  m_sequence = sequence;
+}
+
+bool Ipv6MobilityBindingUpdateHeader::GetFlagA () const
+{
+  return m_flagA;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetFlagA (bool a)
+{
+  m_flagA = a;
+}
+
+bool Ipv6MobilityBindingUpdateHeader::GetFlagH () const
+{
+  return m_flagH;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetFlagH (bool h)
+{
+  m_flagH = h;
+}
+
+bool Ipv6MobilityBindingUpdateHeader::GetFlagL () const
+{
+  return m_flagL;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetFlagL (bool l)
+{
+  m_flagL = l;
+}
+
+bool Ipv6MobilityBindingUpdateHeader::GetFlagK () const
+{
+  return m_flagK;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetFlagK (bool k)
+{
+  m_flagK = k;
+}
+
+bool Ipv6MobilityBindingUpdateHeader::GetFlagM () const
+{
+  return m_flagM;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetFlagM (bool m)
+{
+  m_flagM = m;
+}
+
+bool Ipv6MobilityBindingUpdateHeader::GetFlagR () const
+{
+  return m_flagR;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetFlagR (bool r)
+{
+  m_flagR = r;
+}
+
+bool Ipv6MobilityBindingUpdateHeader::GetFlagP () const
+{
+  return m_flagP;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetFlagP (bool p)
+{
+  m_flagP = p;
+}
+
+uint16_t Ipv6MobilityBindingUpdateHeader::GetReserved2 () const
+{
+  return m_reserved2;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetReserved2 (uint16_t reserved2)
+{
+  m_reserved2 = reserved2;
+}
+
+uint16_t Ipv6MobilityBindingUpdateHeader::GetLifetime () const
+{
+  return m_lifetime;
+}
+
+void Ipv6MobilityBindingUpdateHeader::SetLifetime (uint16_t lifetime)
+{
+  m_lifetime = lifetime;
+}
+
+void Ipv6MobilityBindingUpdateHeader::Print (std::ostream& os) const
+{
+  os << "( payload_proto = " << (uint32_t)GetPayloadProto() << " header_len = " << (uint32_t)GetHeaderLen() << " mh_type = " << (uint32_t)GetMhType() << " checksum = " << (uint32_t)GetChecksum();
+  os << " sequence = " << (uint32_t)GetSequence () << ")";
+}
+
+uint32_t Ipv6MobilityBindingUpdateHeader::GetSerializedSize () const
+{
+  return 12 + MobilityOptionField::GetSerializedSize();
+}
+
+void Ipv6MobilityBindingUpdateHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  uint32_t reserved2 = m_reserved2;
+
+  i.WriteU8 (GetPayloadProto());
+  
+  i.WriteU8 ((uint8_t) (( GetSerializedSize() >> 3) - 1));
+  i.WriteU8 (GetMhType());
+  i.WriteU8 (GetReserved());
+  
+  i.WriteU16 (0);
+  
+  i.WriteHtonU16 (m_sequence);
+  
+  if (m_flagA) {
+    reserved2 |= (uint16_t)(1 << 15);
+  }
+  
+  if (m_flagH) {
+    reserved2 |= (uint16_t)(1 << 14);
+  }
+  
+  if (m_flagL) {
+    reserved2 |= (uint16_t)(1 << 13);
+  }
+  
+  if (m_flagK) {
+    reserved2 |= (uint16_t)(1 << 12);
+  }
+  
+  if (m_flagM) {
+    reserved2 |= (uint16_t)(1 << 11);
+  }
+  
+  if (m_flagR) {
+    reserved2 |= (uint16_t)(1 << 10);
+  }
+  
+  if (m_flagP) {
+    reserved2 |= (uint16_t)(1 << 9);
+  }
+  
+  i.WriteHtonU16 (reserved2);
+  i.WriteHtonU16 (m_lifetime);
+  
+  MobilityOptionField::Serialize(i);
+}
+
+uint32_t Ipv6MobilityBindingUpdateHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+
+  SetPayloadProto(i.ReadU8 ());
+  SetHeaderLen(i.ReadU8 ());
+  SetMhType(i.ReadU8 ());
+  SetReserved(i.ReadU8 ());
+  
+  SetChecksum(i.ReadU16 ());
+  
+  m_sequence = i.ReadNtohU16 ();
+  
+  m_reserved2 = i.ReadNtohU16 ();
+  
+  m_flagA = false;
+  m_flagH = false;
+  m_flagL = false;
+  m_flagK = false;
+  m_flagM = false;
+  m_flagR = false;
+  m_flagP = false;
+  
+  if (m_reserved2 & (1 << 15))
+    {
+      m_flagA = true;
+    }
+
+  if (m_reserved2 & (1 << 14))
+    {
+      m_flagH = true;
+    }
+
+  if (m_reserved2 & (1 << 13))
+    {
+      m_flagL = true;
+    }
+
+  if (m_reserved2 & (1 << 12))
+    {
+      m_flagK = true;
+    }
+
+  if (m_reserved2 & (1 << 11))
+    {
+      m_flagM = true;
+    }
+
+  if (m_reserved2 & (1 << 10))
+    {
+      m_flagR = true;
+    }
+
+  if (m_reserved2 & (1 << 9))
+    {
+      m_flagP = true;
+    }
+
+  m_lifetime = i.ReadNtohU16 ();
+  
+  MobilityOptionField::Deserialize(i, (( GetHeaderLen() + 1 ) << 3 ) - GetOptionsOffset() );
+  
+  return GetSerializedSize ();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityBindingAckHeader);
+
+TypeId Ipv6MobilityBindingAckHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityBindingAckHeader")
+    .SetParent<Ipv6MobilityHeader> ()
+    .AddConstructor<Ipv6MobilityBindingAckHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityBindingAckHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityBindingAckHeader::Ipv6MobilityBindingAckHeader ()
+: MobilityOptionField(12)
+{
+  SetHeaderLen(0);
+  SetMhType(IPV6_MOBILITY_BINDING_ACKNOWLEDGEMENT);
+  SetReserved(0);
+  SetChecksum(0);
+  
+  SetStatus(0);
+  SetFlagK(0);
+  SetFlagR(0);
+  SetFlagP(0);
+  SetReserved2(0);
+  SetSequence(0);
+  SetLifetime(0);
+}
+
+Ipv6MobilityBindingAckHeader::~Ipv6MobilityBindingAckHeader ()
+{
+}
+
+uint8_t Ipv6MobilityBindingAckHeader::GetStatus () const
+{
+  return m_status;
+}
+
+void Ipv6MobilityBindingAckHeader::SetStatus (uint8_t status)
+{
+  m_status = status;
+}
+
+bool Ipv6MobilityBindingAckHeader::GetFlagK () const
+{
+  return m_flagK;
+}
+
+void Ipv6MobilityBindingAckHeader::SetFlagK (bool k)
+{
+  m_flagK = k;
+}
+
+bool Ipv6MobilityBindingAckHeader::GetFlagR () const
+{
+  return m_flagR;
+}
+
+void Ipv6MobilityBindingAckHeader::SetFlagR (bool r)
+{
+  m_flagR = r;
+}
+
+bool Ipv6MobilityBindingAckHeader::GetFlagP () const
+{
+  return m_flagP;
+}
+
+void Ipv6MobilityBindingAckHeader::SetFlagP (bool p)
+{
+  m_flagP = p;
+}
+
+uint8_t Ipv6MobilityBindingAckHeader::GetReserved2 () const
+{
+  return m_reserved2;
+}
+
+void Ipv6MobilityBindingAckHeader::SetReserved2 (uint8_t reserved2)
+{
+  m_reserved2 = reserved2;
+}
+
+uint16_t Ipv6MobilityBindingAckHeader::GetSequence () const
+{
+  return m_sequence;
+}
+
+void Ipv6MobilityBindingAckHeader::SetSequence (uint16_t sequence)
+{
+  m_sequence = sequence;
+}
+
+uint16_t Ipv6MobilityBindingAckHeader::GetLifetime () const
+{
+  return m_lifetime;
+}
+
+void Ipv6MobilityBindingAckHeader::SetLifetime (uint16_t lifetime)
+{
+  m_lifetime = lifetime;
+}
+
+void Ipv6MobilityBindingAckHeader::Print (std::ostream& os) const
+{
+  os << "( payload_proto = " << (uint32_t)GetPayloadProto() << " header_len = " << (uint32_t)GetHeaderLen() << " mh_type = " << (uint32_t)GetMhType() << " checksum = " << (uint32_t)GetChecksum();
+  os << " status = " << (uint32_t)GetStatus() << " sequence = " << (uint32_t)GetSequence () << ")";
+}
+
+uint32_t Ipv6MobilityBindingAckHeader::GetSerializedSize () const
+{
+  return 12 + MobilityOptionField::GetSerializedSize();
+}
+
+void Ipv6MobilityBindingAckHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  uint32_t reserved2 = m_reserved2;
+
+  i.WriteU8 (GetPayloadProto());
+  
+  i.WriteU8 ( (uint8_t) (( GetSerializedSize() >> 3) - 1) );
+  i.WriteU8 (GetMhType());
+  i.WriteU8 (GetReserved());
+  i.WriteU16 (0);
+  
+  i.WriteU8 (m_status);
+  
+  if (m_flagK) {
+    reserved2 |= (uint8_t)(1 << 7);
+  }
+  
+  if (m_flagR) {
+    reserved2 |= (uint8_t)(1 << 6);
+  }
+  
+  if (m_flagP) {
+    reserved2 |= (uint8_t)(1 << 5);
+  }
+  
+  i.WriteU8 (reserved2);
+  i.WriteHtonU16 (m_sequence);
+  i.WriteHtonU16 (m_lifetime);
+  
+  MobilityOptionField::Serialize(i);
+}
+
+uint32_t Ipv6MobilityBindingAckHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+
+  SetPayloadProto(i.ReadU8 ());
+  SetHeaderLen(i.ReadU8 ());
+  SetMhType(i.ReadU8 ());
+  SetReserved(i.ReadU8 ());
+  
+  SetChecksum(i.ReadU16 ());
+  
+  m_status = i.ReadU8 ();
+  
+  m_reserved2 = i.ReadU8 ();
+  
+  m_flagK = false;
+  m_flagR = false;
+  m_flagP = false;
+  
+  if (m_reserved2 & (1 << 7))
+    {
+      m_flagK = true;
+    }
+
+  if (m_reserved2 & (1 << 6))
+    {
+      m_flagR = true;
+    }
+
+  if (m_reserved2 & (1 << 5))
+    {
+      m_flagP = true;
+    }
+
+  m_sequence = i.ReadNtohU16 ();
+  m_lifetime = i.ReadNtohU16 ();
+
+  MobilityOptionField::Deserialize(i, (( GetHeaderLen() + 1 ) << 3 ) - 16 );
+  
+  return GetSerializedSize ();
+}
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-header.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,742 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_MOBILITY_HEADER_H
+#define IPV6_MOBILITY_HEADER_H
+
+#include <list>
+
+#include "ns3/header.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/packet.h"
+
+#include "ipv6-mobility-option-header.h"
+
+namespace ns3
+{
+
+class Identifier;
+
+/**
+ * \class Ipv6MobilityHeader
+ * \brief Ipv6Mobility header.
+ */
+class Ipv6MobilityHeader : public Header
+{
+public:
+   enum MhType_e
+  {
+    IPV6_MOBILITY_BINDING_REFRESH_REQUEST = 0,
+	IPV6_MOBILITY_HOME_TEST_INIT,
+	IPV6_MOBILITY_CARE_OF_TEST_INIT,
+	IPV6_MOBILITY_HOME_TEST,
+	IPV6_MOBILITY_CARE_OF_TEST,
+	IPV6_MOBILITY_BINDING_UPDATE,
+	IPV6_MOBILITY_BINDING_ACKNOWLEDGEMENT,
+	IPV6_MOBILITY_BINDING_ERROR
+  };
+   
+   enum OptionType_e
+  {
+    IPV6_MOBILITY_OPT_PAD1 = 0,
+	IPV6_MOBILITY_OPT_PADN,
+	IPV6_MOBILITY_OPT_BINDING_REFRESH_ADVICE,
+	IPV6_MOBILITY_OPT_ALTERNATE_CARE_OF_ADDRESS,
+	IPV6_MOBILITY_OPT_NONCE_INDICES,
+	IPV6_MOBILITY_OPT_BINDING_AUTHORIZATION_DATA,
+	
+	IPV6_MOBILITY_OPT_MOBILE_NODE_IDENTIFIER = 8
+	
+	/* PMIPv6 options */
+	,
+	IPV6_MOBILITY_OPT_HOME_NETWORK_PREFIX = 22,
+	IPV6_MOBILITY_OPT_HANDOFF_INDICATOR,
+	IPV6_MOBILITY_OPT_ACCESS_TECHNOLOGY_TYPE,
+	IPV6_MOBILITY_OPT_MOBILE_NODE_LINK_LAYER_IDENTIFIER = 25,
+	IPV6_MOBILITY_OPT_LINK_LOCAL_ADDRESS,
+	IPV6_MOBILITY_OPT_TIMESTAMP
+  };
+
+  enum BAStatus_e {
+    BA_STATUS_BINDING_UPDATE_ACCEPTED = 0,
+	BA_STATUS_REASON_UNSPECIFIED = 128,
+	BA_STATUS_ADMINISTRATIVELY_PROHIBITED,
+	BA_STATUS_INSUFFICIENT_RESOURCES = 130
+	
+    /* PMIPv6 extended BA status */
+	,
+    BA_STATUS_PROXY_REG_NOT_ENABLED = 152,
+	BA_STATUS_NOT_LMA_FOR_THIS_MOBILE_NODE,
+	BA_STATUS_NOT_AUTHORIZED_FOR_PROXY_REG,
+	BA_STATUS_MAG_NOT_AUTHORIZED_FOR_HOME_NETWORK_PREFIX = 155,
+	BA_STATUS_TIMESTAMP_MISMATCH,
+	BA_STATUS_TIMESTAMP_LOWER_THAN_PREV_ACCEPTED,
+	BA_STATUS_MISSING_HOME_NETWORK_PREFIX_OPTION,
+	BA_STATUS_BCE_PBU_PREFIX_SET_DO_NOT_MATCH,
+	BA_STATUS_MISSING_MN_IDENTIFIER_OPTION = 160,
+	BA_STATUS_MISSING_HANDOFF_INDICATOR_OPTION,
+	BA_STATUS_MISSING_ACCESS_TECH_TYPE_OPTION
+  };
+  
+  enum OptionHandoffIndicator_e {
+    OPT_HI_RESERVED = 0,
+	OPT_HI_ATTACH_OVER_NEW_INTERFACE,
+	OPT_HI_HANDOFF_BETWEEN_DIFFERENT_INTERFACES,
+	OPT_HI_HANDOFF_BETWEEN_MAGS_FOR_SAME_INTERFACE,
+	OPT_HI_HANDOFF_STATE_UNKNOWN,
+	OPT_HI_STATE_NOT_CHANGED
+  };
+  
+  enum OptionAccessTechType_e {
+    OPT_ATT_RESERVED = 0,
+	OPT_ATT_VIRTUAL,
+	OPT_ATT_PPP,
+	OPT_ATT_IEEE_802_3,
+	OPT_ATT_IEEE_802_11ABG,
+	OPT_ATT_IEEE_802_16E
+  };
+  
+  /**
+   * \brief Get the UID of this class.
+   * \return UID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief Get the instance type ID.
+   * \return instance type ID
+   */
+  virtual TypeId GetInstanceTypeId () const;
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MobilityHeader ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityHeader ();
+  
+  /**
+   * \brief Get the payload proto field.
+   * \return payload proto (MUST BE 59)
+   */
+  uint8_t GetPayloadProto () const;
+
+  /**
+   * \brief Set the payload_proto.
+   * \param payload_proto payload protocol
+   */
+  void SetPayloadProto (uint8_t payload_proto);
+
+  /**
+   * \brief Get the header len field.
+   * \return the unit of 8 octets
+   */
+  uint8_t GetHeaderLen () const;
+
+  /**
+   * \brief Set the header_len.
+   * \param header_len 8octets of header length
+   */
+  void SetHeaderLen (uint8_t header_len);
+
+  /**
+   * \brief Get the mh type field.
+   * \return the mh type
+   */
+  uint8_t GetMhType () const;
+
+  /**
+   * \brief Set the mh type.
+   * \param mh_type the mh type
+   */
+  void SetMhType (uint8_t mh_type);
+
+  /**
+   * \brief Get the reserved.
+   * \return reserved
+   */
+  uint8_t GetReserved () const;
+
+  /**
+   * \brief Set the reserved.
+   * \param reserved to set
+   */
+  void SetReserved (uint8_t reserved);
+
+  /**
+   * \brief Get the checksum.
+   * \return checksum
+   */
+  uint16_t GetChecksum () const;
+
+  /**
+   * \brief Set the checksum.
+   * \param checksum to set
+   */
+  void SetChecksum (uint16_t checksum);
+
+    /**
+   * \brief Print informations.
+   * \param os output stream
+   */
+  virtual void Print (std::ostream& os) const;
+
+  /**
+   * \brief Get the serialized size.
+   * \return serialized size
+   */
+  virtual uint32_t GetSerializedSize () const;
+
+  /**
+   * \brief Serialize the packet.
+   * \param start start offset
+   */
+  virtual void Serialize (Buffer::Iterator start) const;
+
+  /**
+   * \brief Deserialize the packet.
+   * \param start start offset
+   * \return length of packet
+   */
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+private:
+  /**
+   * \brief The next header.
+   */
+  uint8_t m_payload_proto;
+
+  /**
+   * \brief The header length.
+   */
+  uint8_t m_header_len;
+  
+   /**
+   * \brief The MH type.
+   */
+  uint8_t m_mh_type;
+  
+  /**
+   * \brief Reserved.
+   */
+  uint8_t m_reserved;
+
+   /**
+   * \brief The checksum.
+   */
+  uint16_t m_checksum;
+
+};
+
+/**
+ * \class MobilityOptionField
+ * \brief Option field for an IPv6MobilityHeader
+ * Enables adding options to an IPv6MobilityHeader
+ *
+ * Implementor's note: Make sure to add the result of
+ * MobilityOptionField::GetSerializedSize () to your IPv6MobilityHeader::GetSerializedSize ()
+ * return value. Call MobilityOptionField::Serialize and MobilityOptionField::Deserialize at the
+ * end of your corresponding IPv6MobilityHeader methods.
+ */
+class MobilityOptionField
+{
+public:
+  /**
+   * \brief Constructor.
+   * \param optionsOffset option offset
+   */
+  MobilityOptionField (uint32_t optionsOffset);
+
+  /**
+   * \brief Destructor.
+   */
+  ~MobilityOptionField ();
+
+  /**
+   * \brief Get the serialized size of the packet.
+   * \return size
+   */
+  uint32_t GetSerializedSize () const;
+
+  /**
+   * \brief Serialize all added options.
+   * \param start Buffer iterator
+   */
+  void Serialize (Buffer::Iterator start) const;
+
+  /**
+   * \brief Deserialize the packet.
+   * \param start Buffer iterator
+   * \param length length
+   * \return size of the packet
+   */
+  uint32_t Deserialize (Buffer::Iterator start, uint32_t length);
+
+  /**
+   * \brief Serialize the option, prepending pad1 or padn option as necessary
+   * \param option the option header to serialize
+   */
+  void AddOption (Ipv6MobilityOptionHeader const& option);
+
+  /**
+   * \brief Get the offset where the options begin, measured from the start of
+   * the extension header.
+   * \return the offset from the start of the extension header
+   */
+  uint32_t GetOptionsOffset ();
+
+  /**
+   * \brief Get the buffer.
+   * \return buffer
+   */
+  Buffer GetOptionBuffer ();
+
+private:
+
+  /**
+   * \brief Calculate padding.
+   * \param alignment alignment
+   */
+  uint32_t CalculatePad (Ipv6MobilityOptionHeader::Alignment alignment) const;
+
+  /**
+   * \brief Data payload.
+   */
+  Buffer m_optionData;
+
+  /**
+   * \brief Offset.
+   */
+  uint32_t m_optionsOffset;
+};
+
+/**
+ * \class Ipv6MobilityBindingUpdateHeader
+ * \brief Ipv6 Mobility Binding Update header.
+ */
+class Ipv6MobilityBindingUpdateHeader : public Ipv6MobilityHeader, public MobilityOptionField
+{
+public:
+  /**
+   * \brief Get the UID of this class.
+   * \return UID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief Get the instance type ID.
+   * \return instance type ID
+   */
+  virtual TypeId GetInstanceTypeId () const;
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MobilityBindingUpdateHeader ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityBindingUpdateHeader ();
+
+  /**
+   * \brief Get the Sequence field.
+   * \return sequence value
+   */
+  uint16_t GetSequence () const;
+
+  /**
+   * \brief Set the sequence field.
+   * \param sequence the sequence value
+   */
+  void SetSequence (uint16_t sequence);
+
+  /**
+   * \brief Get the A flag.
+   * \return A flag
+   */
+  bool GetFlagA() const;
+  
+  /**
+   * \brief Set the A flag.
+   * \param a value
+   */
+  void SetFlagA(bool a);
+
+  /**
+   * \brief Get the H flag.
+   * \return H flag
+   */
+  bool GetFlagH() const;
+  
+  /**
+   * \brief Set the H flag.
+   * \param h value
+   */
+  void SetFlagH(bool h);
+
+  /**
+   * \brief Get the L flag.
+   * \return L flag
+   */
+  bool GetFlagL() const;
+  
+  /**
+   * \brief Set the L flag.
+   * \param l value
+   */
+  void SetFlagL(bool l);
+
+  /**
+   * \brief Get the K flag.
+   * \return K flag
+   */
+  bool GetFlagK() const;
+  
+  /**
+   * \brief Set the K flag.
+   * \param k value
+   */
+  void SetFlagK(bool k);
+
+  /**
+   * \brief Get the M flag.
+   * \return M flag
+   */
+  bool GetFlagM() const;
+  
+  /**
+   * \brief Set the M flag.
+   * \param m value
+   */
+  void SetFlagM(bool m);
+
+  /**
+   * \brief Get the R flag.
+   * \return R flag
+   */
+  bool GetFlagR() const;
+  
+  /**
+   * \brief Set the R flag.
+   * \param r value
+   */
+  void SetFlagR(bool r);
+
+  /**
+   * \brief Get the P flag.
+   * \return P flag
+   */
+  bool GetFlagP() const;
+  
+  /**
+   * \brief Set the P flag.
+   * \param p value
+   */
+  void SetFlagP(bool p);
+
+  /**
+   * \brief Get the Reserved value.
+   * \return Reserved value
+   */
+  uint16_t GetReserved2() const;
+  
+  /**
+   * \brief Set the Reserved.
+   * \param reserved reserved value
+   */
+  void SetReserved2(uint16_t reserved2);
+
+  /**
+   * \brief Get the Lifetime value.
+   * \return Lifetime
+   */
+  uint16_t GetLifetime() const;
+  
+  /**
+   * \brief Set the Lifetime.
+   * \param lifetime lifetime value
+   */
+  void SetLifetime(uint16_t lifetime);
+
+  /**
+   * \brief Print informations.
+   * \param os output stream
+   */
+  virtual void Print (std::ostream& os) const;
+
+  /**
+   * \brief Get the serialized size.
+   * \return serialized size
+   */
+  virtual uint32_t GetSerializedSize () const;
+
+  /**
+   * \brief Serialize the packet.
+   * \param start start offset
+   */
+  virtual void Serialize (Buffer::Iterator start) const;
+
+  /**
+   * \brief Deserialize the packet.
+   * \param start start offset
+   * \return length of packet
+   */
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+private:
+
+  /**
+   * \brief The Sequence field
+   */
+  uint16_t m_sequence;
+
+  /**
+   * \brief The A flag.
+   */
+  bool m_flagA;
+
+  /**
+   * \brief The H flag.
+   */
+  bool m_flagH;
+
+  /**
+   * \brief The L flag.
+   */
+  bool m_flagL;
+
+  /**
+   * \brief The K flag.
+   */
+  bool m_flagK;
+
+  /**
+   * \brief The M flag.
+   */
+  bool m_flagM;
+
+  /**
+   * \brief The R flag.
+   */
+  bool m_flagR;
+
+  /**
+   * \brief The P flag.
+   */
+  bool m_flagP;
+
+  /**
+   * \brief The reserved value.
+   */
+  uint16_t m_reserved2;
+
+  /**
+   * \brief The Lifetime.
+   */
+  uint16_t m_lifetime;
+};
+
+/**
+ * \class Ipv6MobilityBindingAckHeader
+ * \brief Ipv6 Mobility Binding Acknowledgement header.
+ */
+class Ipv6MobilityBindingAckHeader : public Ipv6MobilityHeader, public MobilityOptionField
+{
+public:
+  /**
+   * \brief Get the UID of this class.
+   * \return UID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief Get the instance type ID.
+   * \return instance type ID
+   */
+  virtual TypeId GetInstanceTypeId () const;
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MobilityBindingAckHeader ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityBindingAckHeader ();
+
+  /**
+   * \brief Get the Status field.
+   * \return status value
+   */
+  uint8_t GetStatus () const;
+
+  /**
+   * \brief Set the status field.
+   * \param status the status value
+   */
+  void SetStatus (uint8_t status);
+  
+  /**
+   * \brief Get the K flag.
+   * \return K flag
+   */
+  bool GetFlagK() const;
+  
+  /**
+   * \brief Set the K flag.
+   * \param k value
+   */
+  void SetFlagK(bool k);
+
+  /**
+   * \brief Get the R flag.
+   * \return R flag
+   */
+  bool GetFlagR() const;
+  
+  /**
+   * \brief Set the R flag.
+   * \param r value
+   */
+  void SetFlagR(bool r);
+
+  /**
+   * \brief Get the P flag.
+   * \return P flag
+   */
+  bool GetFlagP() const;
+  
+  /**
+   * \brief Set the P flag.
+   * \param p value
+   */
+  void SetFlagP(bool p);
+
+  /**
+   * \brief Get the Reserved2 field.
+   * \return reserved2 value
+   */
+  uint8_t GetReserved2 () const;
+
+  /**
+   * \brief Set the reserved2 field.
+   * \param reserved2 the reserved2 value
+   */
+  void SetReserved2 (uint8_t reserved2);
+  
+  /**
+   * \brief Get the Sequence field.
+   * \return sequence value
+   */
+  uint16_t GetSequence () const;
+
+  /**
+   * \brief Set the sequence field.
+   * \param sequence the sequence value
+   */
+  void SetSequence (uint16_t sequence);
+
+  /**
+   * \brief Get the Lifetime value.
+   * \return Lifetime
+   */
+  uint16_t GetLifetime() const;
+  
+  /**
+   * \brief Set the Lifetime.
+   * \param lifetime lifetime value
+   */
+  void SetLifetime(uint16_t lifetime);
+
+  /**
+   * \brief Print informations.
+   * \param os output stream
+   */
+  virtual void Print (std::ostream& os) const;
+
+  /**
+   * \brief Get the serialized size.
+   * \return serialized size
+   */
+  virtual uint32_t GetSerializedSize () const;
+
+  /**
+   * \brief Serialize the packet.
+   * \param start start offset
+   */
+  virtual void Serialize (Buffer::Iterator start) const;
+
+  /**
+   * \brief Deserialize the packet.
+   * \param start start offset
+   * \return length of packet
+   */
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+private:
+
+  /**
+   * \brief The status value.
+   */
+  uint8_t m_status;
+
+  /**
+   * \brief The K flag.
+   */
+  bool m_flagK;
+
+  /**
+   * \brief The R flag.
+   */
+  bool m_flagR;
+
+  /**
+   * \brief The P flag.
+   */
+  bool m_flagP;
+
+  /**
+   * \brief The reserved value.
+   */
+  uint8_t m_reserved2;
+
+  /**
+   * \brief The Sequence field
+   */
+  uint16_t m_sequence;
+
+  /**
+   * \brief The Lifetime.
+   */
+  uint16_t m_lifetime;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_MOBILITY_HEADER_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.cc	2014-02-03 16:08:43.000000000 +0100
@@ -0,0 +1,304 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include <stdio.h>
+#include <sstream>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/boolean.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/ipv6-interface.h"
+
+#include "identifier.h"
+#include "ipv6-mobility-header.h"
+#include "ipv6-mobility-demux.h"
+#include "ipv6-mobility-option.h"
+#include "ipv6-mobility-option-header.h"
+#include "ipv6-mobility-option-demux.h"
+#include "ipv6-mobility-l4-protocol.h"
+
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6MobilityL4Protocol");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityL4Protocol);
+
+const uint8_t Ipv6MobilityL4Protocol::PROT_NUMBER = 135;
+
+const double Ipv6MobilityL4Protocol::MAX_BINDING_LIFETIME = (int)0xffff<<2;
+
+const double Ipv6MobilityL4Protocol::INITIAL_BINDING_ACK_TIMEOUT_FIRSTREG = 1.5;
+
+const double Ipv6MobilityL4Protocol::INITIAL_BINDING_ACK_TIMEOUT_REREG = 1.0;
+
+const uint8_t Ipv6MobilityL4Protocol::MAX_BINDING_UPDATE_RETRY_COUNT = 3;
+
+const uint32_t Ipv6MobilityL4Protocol::MIN_DELAY_BEFORE_BCE_DELETE = 10000;
+
+const uint32_t Ipv6MobilityL4Protocol::MIN_DELAY_BEFORE_NEW_BCE_ASSIGN = 1500;
+
+const uint32_t Ipv6MobilityL4Protocol::TIMESTAMP_VALIDITY_WINDOW = 300;
+
+TypeId Ipv6MobilityL4Protocol::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityL4Protocol")
+    .SetParent<Ipv6L4Protocol> ()
+    .AddConstructor<Ipv6MobilityL4Protocol> ()
+    ;
+  return tid;
+}
+
+Ipv6MobilityL4Protocol::Ipv6MobilityL4Protocol ()
+  : m_node (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6MobilityL4Protocol::~Ipv6MobilityL4Protocol ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6MobilityL4Protocol::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_node = 0;
+  Ipv6L4Protocol::DoDispose ();
+
+}
+
+void Ipv6MobilityL4Protocol::NotifyNewAggregate ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (m_node == 0)
+    {
+      Ptr<Node> node = this->GetObject<Node> ();
+      if (node != 0)
+        {
+          Ptr<Ipv6L3Protocol> ipv6 = this->GetObject<Ipv6L3Protocol> ();
+          
+          if (ipv6 != 0)
+            {
+              SetNode (node);
+              ipv6->Insert (this);
+            }
+        }
+    }
+  Ipv6L4Protocol::NotifyNewAggregate ();
+}
+
+void Ipv6MobilityL4Protocol::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (this << node);
+  m_node = node;
+}
+
+Ptr<Node> Ipv6MobilityL4Protocol::GetNode (void)
+{
+  NS_LOG_FUNCTION_NOARGS();
+  return m_node;
+}
+
+int Ipv6MobilityL4Protocol::GetProtocolNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return PROT_NUMBER;
+}
+
+int Ipv6MobilityL4Protocol::GetVersion () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return 1;
+}
+
+void Ipv6MobilityL4Protocol::SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
+{
+  NS_LOG_FUNCTION (this << packet << src << dst << (uint32_t)ttl);
+  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+  SocketIpTtlTag tag;
+  NS_ASSERT (ipv6 != 0);
+
+  tag.SetTtl (ttl);
+  packet->AddPacketTag (tag);
+  ipv6->Send (packet, src, dst, PROT_NUMBER, 0);
+}
+enum Ipv6L4Protocol::RxStatus_e Ipv6MobilityL4Protocol::Receive (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << header);
+  return Ipv6L4Protocol::RX_ENDPOINT_UNREACH;
+}
+
+enum IpL4Protocol::RxStatus Ipv6MobilityL4Protocol::Receive (Ptr<Packet> packet, Ipv6Header const &header, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << header.GetSourceAddress () << header.GetDestinationAddress () << interface);
+  Ptr<Packet> p = packet->Copy ();
+  Ptr<Ipv6MobilityDemux> ipv6MobilityDemux = GetObject<Ipv6MobilityDemux>();
+  Ptr<Ipv6Mobility> ipv6Mobility = 0;
+  Ipv6MobilityHeader mh;
+  
+  p->PeekHeader (mh);
+  
+  ipv6Mobility = ipv6MobilityDemux -> GetMobility ( mh.GetMhType() );
+  
+  if(ipv6Mobility)
+    {
+	  ipv6Mobility -> Process (p, src, dst, interface);
+	}
+  else
+    {
+	  NS_LOG_FUNCTION( "Mobility Packet with Unknown MhType (" << (uint32_t)mh.GetMhType() << ")" );
+	}
+  return Ipv6L4Protocol::RX_OK;
+}
+
+void Ipv6MobilityL4Protocol::RegisterMobility()
+{
+  Ptr<Ipv6MobilityDemux> ipv6MobilityDemux = CreateObject<Ipv6MobilityDemux>();
+  ipv6MobilityDemux -> SetNode( m_node );
+  
+  m_node -> AggregateObject( ipv6MobilityDemux );
+  
+  Ptr<Ipv6MobilityBindingUpdate> bu = CreateObject<Ipv6MobilityBindingUpdate>();
+  bu->SetNode(m_node);
+  ipv6MobilityDemux->Insert(bu);
+  
+  Ptr<Ipv6MobilityBindingAck> ba = CreateObject<Ipv6MobilityBindingAck>();
+  ba->SetNode(m_node);
+  ipv6MobilityDemux->Insert(ba);  
+}
+
+void Ipv6MobilityL4Protocol::RegisterMobilityOptions()
+{
+  Ptr<Ipv6MobilityOptionDemux> ipv6MobilityOptionDemux = CreateObject<Ipv6MobilityOptionDemux>();
+  ipv6MobilityOptionDemux -> SetNode( m_node );
+  
+  m_node -> AggregateObject( ipv6MobilityOptionDemux );
+  
+  Ptr<Ipv6MobilityOptionPad1> pad1 = CreateObject<Ipv6MobilityOptionPad1>();
+  pad1->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(pad1);
+  
+  Ptr<Ipv6MobilityOptionPadn> padn = CreateObject<Ipv6MobilityOptionPadn>();
+  padn->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(padn);
+  
+  //for PMIPv6
+  Ptr<Ipv6MobilityOptionMobileNodeIdentifier> nai = CreateObject<Ipv6MobilityOptionMobileNodeIdentifier>();
+  nai->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(nai);
+  
+  Ptr<Ipv6MobilityOptionHomeNetworkPrefix> hnp = CreateObject<Ipv6MobilityOptionHomeNetworkPrefix>();
+  hnp->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(hnp);
+  
+  Ptr<Ipv6MobilityOptionHandoffIndicator> hi = CreateObject<Ipv6MobilityOptionHandoffIndicator>();
+  hi->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(hi);
+  
+  Ptr<Ipv6MobilityOptionAccessTechnologyType> att = CreateObject<Ipv6MobilityOptionAccessTechnologyType>();
+  att->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(att);
+  
+  Ptr<Ipv6MobilityOptionMobileNodeLinkLayerIdentifier> llid = CreateObject<Ipv6MobilityOptionMobileNodeLinkLayerIdentifier>();
+  llid->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(llid);
+  
+  Ptr<Ipv6MobilityOptionLinkLocalAddress> lla = CreateObject<Ipv6MobilityOptionLinkLocalAddress>();
+  lla->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(lla);
+  
+  Ptr<Ipv6MobilityOptionTimestamp> timestamp = CreateObject<Ipv6MobilityOptionTimestamp>();
+  timestamp->SetNode(m_node);
+  ipv6MobilityOptionDemux->Insert(timestamp);
+}
+
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-l4-protocol.h	2014-02-03 16:00:12.000000000 +0100
@@ -0,0 +1,217 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_MOBILITY_L4_PROTOCOL_H
+#define IPV6_MOBILITY_L4_PROTOCOL_H
+
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-l4-protocol.h"
+
+
+namespace ns3
+{
+
+class Node;
+class Packet;
+
+/**
+ * \class Ipv6MobilityL4Protocol
+ * \brief An implementation of the Mobile Ipv6 protocol.
+ */
+class Ipv6MobilityL4Protocol : public IpL4Protocol
+{
+public:
+  /**
+   * \brief Interface ID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief IPv6 Mobility protocol number (135).
+   */
+  static const uint8_t PROT_NUMBER;
+  
+  /**
+   * \brief Binding Update lifetime (0x3fffc seconds)
+   */
+  static const double MAX_BINDING_LIFETIME;
+
+  /**
+   * \brief Initial Binding Ack Timeout for First Registration (1.5 seconds)
+   */
+  static const double INITIAL_BINDING_ACK_TIMEOUT_FIRSTREG;
+
+  /**
+   * \brief Initial Binding Ack Timeout for Re-Registration (1 second)
+   */
+  static const double INITIAL_BINDING_ACK_TIMEOUT_REREG;
+  
+  /**
+   * \brief Binding Update Maximum retry count (=3)
+   */  
+  static const uint8_t MAX_BINDING_UPDATE_RETRY_COUNT;
+  
+  /**
+   * \brief The amount of time in milliseconds the local mobility anchor before delete BCE entry (10000ms)
+   */  
+  static const uint32_t MIN_DELAY_BEFORE_BCE_DELETE;
+  
+  /**
+   * \brief The amount of time the LMA MUST wait for the de-reg messsage (1500ms)
+   */  
+  static const uint32_t MIN_DELAY_BEFORE_NEW_BCE_ASSIGN;
+
+  /**
+   * \brief The maximum amount of time difference between timestamps
+   */  
+  static const uint32_t TIMESTAMP_VALIDITY_WINDOW;
+
+  /**
+   * \brief Get PMIPv6 protocol number.
+   * \return protocol number
+   */
+  static uint16_t GetStaticProtocolNumber ();
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MobilityL4Protocol ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityL4Protocol ();
+
+  /**
+   * \brief Set the node.
+   * \param node the node to set
+   */
+  void SetNode (Ptr<Node> node);
+  
+  /**
+   * \brief Get the node.
+   * \return node
+   */
+  Ptr<Node> GetNode (void);
+
+    /**
+   * \brief This method is called by AddAgregate and completes the aggregation
+   * by setting the node in the Ipv6 Mobility stack.
+   */
+  virtual void NotifyNewAggregate ();
+
+  /**
+   * \brief Get the protocol number.
+   * \return protocol number
+   */
+  virtual int GetProtocolNumber () const;
+
+  /**
+   * \brief Get the version of the protocol.
+   * \return version
+   */
+  virtual int GetVersion () const;
+
+  /**
+   * \brief Send a packet via IPv6 Mobility, note that packet already contains IPv6 Mobility header.
+   * \param packet the packet to send which contains IPv6 Mobility header
+   * \param src source address
+   * \param dst destination address
+   * \param ttl next hop limit
+   */
+  void SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl);
+  /**
+   * \brief Receive method.
+   * \param p the packet
+   * \param src source address
+   * \param dst destination address
+   * \param interface the interface from which the packet is coming
+   */
+  virtual enum Ipv6L4Protocol::RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+
+  /**
+   * \brief Register the IPv6 Mobility.
+   */
+  virtual void RegisterMobility();
+
+  /**
+   * \brief Register the IPv6 Mobility Options.
+   */
+  virtual void RegisterMobilityOptions ();
+
+protected:
+ 
+  /**
+   * \brief Dispose this object.
+   */
+  virtual void DoDispose ();
+  
+private:
+
+  /**
+   * \brief The node.
+   */
+  Ptr<Node> m_node;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_MOBILITY_L4_PROTOCOL_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,528 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#include "ns3/log.h"
+#include "ns3/uinteger.h"
+#include "ns3/identifier.h"
+#include "ipv6-mobility-option.h"
+#include "ipv6-mobility-option-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6MobilityOption");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOption);
+
+TypeId Ipv6MobilityOption::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOption")
+    .SetParent<Object>()
+	.AddAttribute ("MobilityOptionNumber", "The IPv6 mobility option number.",
+	               UintegerValue (0),
+				   MakeUintegerAccessor (&Ipv6MobilityOption::GetMobilityOptionNumber),
+				   MakeUintegerChecker<uint8_t> ())
+	;
+  return tid;
+}
+
+Ipv6MobilityOption::~Ipv6MobilityOption()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6MobilityOption::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (this << node);
+  m_node = node;
+}
+
+Ipv6MobilityOptionBundle::Ipv6MobilityOptionBundle()
+ : m_mnIdentifier(),
+   m_mnLinkIdentifier(),
+   m_accessTechnologyType(0),
+   m_handoffIndicator(0),
+   m_timestamp(Seconds(0.0))
+{
+  NS_LOG_FUNCTION_NOARGS();
+}
+
+Identifier Ipv6MobilityOptionBundle::GetMnIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_mnIdentifier;
+}
+
+void Ipv6MobilityOptionBundle::SetMnIdentifier(Identifier mnId)
+{
+  NS_LOG_FUNCTION ( this << mnId );
+
+  m_mnIdentifier = mnId;
+}
+
+Identifier Ipv6MobilityOptionBundle::GetMnLinkIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_mnLinkIdentifier;
+}
+
+void Ipv6MobilityOptionBundle::SetMnLinkIdentifier(Identifier mnLinkId)
+{
+  NS_LOG_FUNCTION ( this << mnLinkId );
+  
+  m_mnLinkIdentifier = mnLinkId;
+}
+
+std::list<Ipv6Address> Ipv6MobilityOptionBundle::GetHomeNetworkPrefixes() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_homeNetworkPrefixes;
+}
+
+void Ipv6MobilityOptionBundle::SetHomeNetworkPrefixes(std::list<Ipv6Address> hnps)
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  m_homeNetworkPrefixes = hnps;
+}
+
+void Ipv6MobilityOptionBundle::AddHomeNetworkPrefix(Ipv6Address addr)
+{
+  NS_LOG_FUNCTION ( this << addr );
+  
+  m_homeNetworkPrefixes.push_back(addr);
+}
+
+Ipv6Address Ipv6MobilityOptionBundle::GetMagLinkAddress() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_magLinkAddress;
+}
+
+void Ipv6MobilityOptionBundle::SetMagLinkAddress(Ipv6Address lla)
+{
+  NS_LOG_FUNCTION ( this << lla );
+  
+  m_magLinkAddress = lla;
+}
+
+uint8_t Ipv6MobilityOptionBundle::GetAccessTechnologyType() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_accessTechnologyType;
+}
+
+void Ipv6MobilityOptionBundle::SetAccessTechnologyType(uint8_t att)
+{
+  NS_LOG_FUNCTION ( this << (uint32_t) att );
+  
+  m_accessTechnologyType = att;
+}
+
+uint8_t Ipv6MobilityOptionBundle::GetHandoffIndicator() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_handoffIndicator;
+}
+
+void Ipv6MobilityOptionBundle::SetHandoffIndicator(uint8_t hi)
+{
+  NS_LOG_FUNCTION ( this << hi );
+  
+  m_handoffIndicator = hi;
+}
+
+Time Ipv6MobilityOptionBundle::GetTimestamp() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_timestamp;
+}
+
+void Ipv6MobilityOptionBundle::SetTimestamp(Time tm)
+{
+  NS_LOG_FUNCTION ( this << tm );
+  
+  m_timestamp = tm;
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionPad1);
+
+TypeId Ipv6MobilityOptionPad1::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionPad1")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionPad1::~Ipv6MobilityOptionPad1()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionPad1::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionPad1::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  Ipv6MobilityOptionPad1Header pad1;
+  
+  p->RemoveHeader(pad1);
+  
+  return pad1.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionPadn);
+
+TypeId Ipv6MobilityOptionPadn::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionPadn")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionPadn::~Ipv6MobilityOptionPadn()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionPadn::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionPadn::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+
+  Ipv6MobilityOptionPadnHeader padn;
+  
+  p->RemoveHeader(padn);
+  
+  return padn.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionMobileNodeIdentifier);
+
+TypeId Ipv6MobilityOptionMobileNodeIdentifier::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionMobileNodeIdentifier")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionMobileNodeIdentifier::~Ipv6MobilityOptionMobileNodeIdentifier()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionMobileNodeIdentifier::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionMobileNodeIdentifier::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet << (uint32_t)offset);
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  Ipv6MobilityOptionMobileNodeIdentifierHeader nai;
+  
+  p->RemoveHeader(nai);
+  
+  if ( nai.GetSubtype() == 1 ) //Network Address Identifier
+    {
+	  bundle.SetMnIdentifier(nai.GetNodeIdentifier());
+	}
+  
+  return nai.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionHomeNetworkPrefix);
+
+TypeId Ipv6MobilityOptionHomeNetworkPrefix::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionHomeNetworkPrefix")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionHomeNetworkPrefix::~Ipv6MobilityOptionHomeNetworkPrefix()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionHomeNetworkPrefix::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionHomeNetworkPrefix::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  Ipv6MobilityOptionHomeNetworkPrefixHeader hnp;
+  
+  p->RemoveHeader(hnp);
+  
+  bundle.AddHomeNetworkPrefix(hnp.GetPrefix());
+ 
+  return hnp.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionHandoffIndicator);
+
+TypeId Ipv6MobilityOptionHandoffIndicator::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionHandoffIndicator")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionHandoffIndicator::~Ipv6MobilityOptionHandoffIndicator()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionHandoffIndicator::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionHandoffIndicator::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ipv6MobilityOptionHandoffIndicatorHeader hi;
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  p->RemoveHeader(hi);
+  
+  bundle.SetHandoffIndicator(hi.GetHandoffIndicator());
+ 
+  return hi.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionAccessTechnologyType);
+
+TypeId Ipv6MobilityOptionAccessTechnologyType::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionAccessTechnologyType")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionAccessTechnologyType::~Ipv6MobilityOptionAccessTechnologyType()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionAccessTechnologyType::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionAccessTechnologyType::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ipv6MobilityOptionAccessTechnologyTypeHeader att;
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  p->RemoveHeader(att);
+  
+  bundle.SetAccessTechnologyType(att.GetAccessTechnologyType());
+ 
+  return att.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionMobileNodeLinkLayerIdentifier);
+
+TypeId Ipv6MobilityOptionMobileNodeLinkLayerIdentifier::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionMobileNodeLinkLayerIdentifier")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionMobileNodeLinkLayerIdentifier::~Ipv6MobilityOptionMobileNodeLinkLayerIdentifier()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionMobileNodeLinkLayerIdentifier::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionMobileNodeLinkLayerIdentifier::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader mnllid;
+  
+  p->RemoveHeader(mnllid);
+  
+  bundle.SetMnLinkIdentifier(mnllid.GetLinkLayerIdentifier());
+ 
+  return mnllid.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionLinkLocalAddress);
+
+TypeId Ipv6MobilityOptionLinkLocalAddress::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionLinkLocalAddress")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionLinkLocalAddress::~Ipv6MobilityOptionLinkLocalAddress()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionLinkLocalAddress::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionLinkLocalAddress::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  Ipv6MobilityOptionLinkLocalAddressHeader lla;
+  
+  p->RemoveHeader(lla);
+  
+  bundle.SetMagLinkAddress(lla.GetLinkLocalAddress());
+ 
+  return lla.GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionTimestamp);
+
+TypeId Ipv6MobilityOptionTimestamp::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionTimestamp")
+    .SetParent<Ipv6MobilityOption>()
+	;
+  return tid;
+}
+
+Ipv6MobilityOptionTimestamp::~Ipv6MobilityOptionTimestamp()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint8_t Ipv6MobilityOptionTimestamp::GetMobilityOptionNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return OPT_NUMBER;
+}
+
+uint8_t Ipv6MobilityOptionTimestamp::Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle)
+{
+  NS_LOG_FUNCTION ( this << packet );
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  p->RemoveAtStart(offset);
+  
+  Ipv6MobilityOptionTimestampHeader timestamp;
+  
+  p->RemoveHeader(timestamp);
+  
+  bundle.SetTimestamp(timestamp.GetTimestamp());
+ 
+  return timestamp.GetSerializedSize();
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,97 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#include "ns3/log.h"
+#include "ns3/object-vector.h"
+
+#include "ipv6-mobility-option-demux.h"
+#include "ipv6-mobility-option.h"
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionDemux);
+
+TypeId Ipv6MobilityOptionDemux::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionDemux")
+    .SetParent<Object> ()
+    .AddAttribute ("MobilityOptions", "The set of IPv6 Mobility options registered with this demux.",
+                   ObjectVectorValue (),
+                   MakeObjectVectorAccessor (&Ipv6MobilityOptionDemux::m_options),
+                   MakeObjectVectorChecker<Ipv6MobilityOption> ())
+    ;
+  return tid;
+}
+
+Ipv6MobilityOptionDemux::Ipv6MobilityOptionDemux ()
+{
+}
+
+Ipv6MobilityOptionDemux::~Ipv6MobilityOptionDemux ()
+{
+}
+
+void Ipv6MobilityOptionDemux::DoDispose ()
+{
+  for (Ipv6MobilityOptionList_t::iterator it = m_options.begin (); it != m_options.end (); it++)
+    {
+      (*it)->Dispose ();
+      *it = 0;
+    }
+  m_options.clear ();
+  m_node = 0;
+  Object::DoDispose ();
+}
+
+void Ipv6MobilityOptionDemux::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+}
+
+void Ipv6MobilityOptionDemux::Insert (Ptr<Ipv6MobilityOption> option)
+{
+  m_options.push_back (option);
+}
+
+Ptr<Ipv6MobilityOption> Ipv6MobilityOptionDemux::GetOption (int optionNumber)
+{
+  for (Ipv6MobilityOptionList_t::iterator i = m_options.begin (); i != m_options.end (); ++i)
+    {
+      if ((*i)->GetMobilityOptionNumber () == optionNumber)
+        {
+          return *i;
+        }
+    }
+  return 0;
+}
+
+void Ipv6MobilityOptionDemux::Remove (Ptr<Ipv6MobilityOption> option)
+{
+  m_options.remove (option);
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-demux.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,110 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_MOBILITY_OPTION_DEMUX_H
+#define IPV6_MOBILITY_OPTION_DEMUX_H
+
+#include <list>
+
+#include "ns3/header.h"
+#include "ns3/object.h"
+#include "ns3/ptr.h"
+
+namespace ns3
+{
+
+class Ipv6MobilityOption;
+class Node;
+
+/**
+ * \class Ipv6MobilityOptionDemux
+ * \brief Ipv6 Mobility Option Demux.
+ */
+class Ipv6MobilityOptionDemux : public Object
+{
+public:
+  /**
+   * \brief The interface ID.
+   * \return type ID
+   */
+  static TypeId GetTypeId (void);
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MobilityOptionDemux ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionDemux ();
+
+  /**
+   * \brief Set the node.
+   * \param node the node to set
+   */
+  void SetNode (Ptr<Node> node);
+
+  /**
+   * \brief Insert a new IPv6 Mobility Option.
+   * \param option the option to insert
+   */
+  void Insert (Ptr<Ipv6MobilityOption> option);
+
+  /**
+   * \brief Get the option corresponding to optionNumber.
+   * \param optionNumber the option number of the option to retrieve
+   * \return a matching IPv6 Mobility option
+   */
+  Ptr<Ipv6MobilityOption> GetOption (int optionNumber);
+
+  /**
+   * \brief Remove an option from this demux.
+   * \param option pointer on the option to remove
+   */
+  void Remove (Ptr<Ipv6MobilityOption> option);
+
+protected:
+  /**
+   * \brief Dispose this object.
+   */
+  virtual void DoDispose();
+
+private:
+  typedef std::list<Ptr<Ipv6MobilityOption> > Ipv6MobilityOptionList_t;
+
+  /**
+   * \brief List of IPv6 Options supported.
+   */
+  Ipv6MobilityOptionList_t m_options;
+
+  /**
+   * \brief The node.
+   */
+  Ptr<Node> m_node;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_MOBILITY_OPTION_DEMUX_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,485 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_MOBILITY_OPTION_H
+#define IPV6_MOBILITY_OPTION_H
+
+#include <list>
+
+#include "ns3/object.h"
+#include "ns3/node.h"
+#include "ns3/ptr.h"
+#include "ns3/header.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/nstime.h"
+#include "ns3/identifier.h"
+
+namespace ns3
+{
+
+class Ipv6MobilityOptionBundle;
+
+/**
+ * \class Ipv6MobilityOption
+ * \brief Ipv6 Mobility Option base
+ *
+ * If you want to implement a new Ipv6 Mobility option, all you have to do is
+ * implement a subclass of this class and add it to an Ipv6MobilityOptionDemux.
+ */
+class Ipv6MobilityOption : public Object
+{
+public:
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOption ();
+  
+  /**
+   * \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 GetMobilityOptionNumber () const = 0;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle) = 0;
+  
+private:
+  /**
+   * \brief The node.
+   */
+  Ptr<Node> m_node;
+};
+
+class Ipv6MobilityOptionBundle
+{
+public:
+  Ipv6MobilityOptionBundle();
+  
+  Identifier GetMnIdentifier() const;
+  void SetMnIdentifier(Identifier mnId);
+  
+  Identifier GetMnLinkIdentifier() const;
+  void SetMnLinkIdentifier(Identifier mnLinkId);
+  
+  std::list<Ipv6Address> GetHomeNetworkPrefixes() const;
+  void SetHomeNetworkPrefixes(std::list<Ipv6Address> hnps);
+  void AddHomeNetworkPrefix(Ipv6Address addr);
+  
+  Ipv6Address GetMagLinkAddress() const;
+  void SetMagLinkAddress(Ipv6Address lla);
+  
+  uint8_t GetAccessTechnologyType() const;
+  void SetAccessTechnologyType(uint8_t att);
+  
+  uint8_t GetHandoffIndicator() const;
+  void SetHandoffIndicator(uint8_t hi);
+  
+  Time GetTimestamp() const;
+  void SetTimestamp(Time tm);
+  
+protected:
+private:
+  //for PMIPv6
+  Identifier m_mnIdentifier;
+  Identifier m_mnLinkIdentifier;
+  std::list<Ipv6Address> m_homeNetworkPrefixes;
+  Ipv6Address m_magLinkAddress;
+  uint8_t m_accessTechnologyType;
+  uint8_t m_handoffIndicator;
+  Time m_timestamp;
+};
+
+/**
+ * \class Ipv6MobilityOptionPad1
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionPad1 : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 0;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionPad1 ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionPadn
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionPadn : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 1;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionPadn ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionMobileNodeIdentifier
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionMobileNodeIdentifier : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 8;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionMobileNodeIdentifier ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionHomeNetworkPrefix
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionHomeNetworkPrefix : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 22;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionHomeNetworkPrefix ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionHandoffIndicator
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionHandoffIndicator : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 23;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionHandoffIndicator ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionAccessTechnologyType
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionAccessTechnologyType : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 24;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionAccessTechnologyType ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionMobileNodeLinkLayerIdentifier
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionMobileNodeLinkLayerIdentifier : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 25;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionMobileNodeLinkLayerIdentifier ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionLinkLocalAddress
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionLinkLocalAddress : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 26;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionLinkLocalAddress ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+/**
+ * \class Ipv6MobilityOptionTimestamp
+ * \brief Ipv6 Mobility Option 
+ */
+class Ipv6MobilityOptionTimestamp : public Ipv6MobilityOption
+{
+public:
+  static const uint8_t OPT_NUMBER = 27;
+  
+  /**
+   * \brief Get the type identificator.
+   * \return type identificator
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionTimestamp ();
+  
+  /**
+   * \brief Get the option number.
+   * \return option number
+   */
+  virtual uint8_t GetMobilityOptionNumber () const;
+  
+  /**
+   * \brief Process method
+   *
+   * Called from Ipv6MobilityL4Protocol::Receive.
+   * \param packet the packet
+   * \param bundle bundle of all option data
+   * \return the processed size
+   */
+  virtual uint8_t Process (Ptr<Packet> packet, uint8_t offset, Ipv6MobilityOptionBundle& bundle);
+  
+private:
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_MOBILITY_OPTION_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,912 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ * Author: Abdelwahed Berguiga <abdelwahed14@gmail.com>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/address-utils.h"
+#include "ns3/log.h"
+#include "ns3/identifier.h"
+#include "ns3/simulator.h"
+
+#include "ipv6-mobility-header.h"
+#include "ipv6-mobility-option-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6MobilityOptionHeader");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionHeader);
+
+TypeId Ipv6MobilityOptionHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionHeader")
+    .SetParent<Header> ()
+    .AddConstructor<Ipv6MobilityOptionHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+
+Ipv6MobilityOptionHeader::Ipv6MobilityOptionHeader ()
+{
+  m_type = 0;
+  m_len = 0;
+}
+
+Ipv6MobilityOptionHeader::~Ipv6MobilityOptionHeader ()
+{
+}
+
+uint8_t Ipv6MobilityOptionHeader::GetType () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_type;
+}
+
+void Ipv6MobilityOptionHeader::SetType (uint8_t type)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_type = type;
+}
+
+uint8_t Ipv6MobilityOptionHeader::GetLength () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_len;
+}
+
+void Ipv6MobilityOptionHeader::SetLength (uint8_t len)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_len = len;
+}
+
+void Ipv6MobilityOptionHeader::Print (std::ostream& os) const
+{
+  os << "( type = " << (uint32_t)GetType () << " length = " << (uint32_t)GetLength () << ")";
+}
+
+uint32_t Ipv6MobilityOptionHeader::GetSerializedSize () const
+{
+  return m_len;
+}
+
+uint32_t Ipv6MobilityOptionHeader::Deserialize (Buffer::Iterator start)
+{
+  //Buffer::Iterator i = start;
+  return GetSerializedSize ();
+}
+
+void Ipv6MobilityOptionHeader::Serialize (Buffer::Iterator start) const
+{
+  //Buffer::Iterator i = start;
+}
+
+Ipv6MobilityOptionHeader::Alignment Ipv6MobilityOptionHeader::GetAlignment () const
+{
+  return (Alignment){1,0};
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6MobilityOptionPad1Header);
+
+TypeId Ipv6MobilityOptionPad1Header::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionPad1Header")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionPad1Header> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionPad1Header::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionPad1Header::Ipv6MobilityOptionPad1Header()
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_PAD1);
+  SetLength(0);
+}
+
+Ipv6MobilityOptionPad1Header::~Ipv6MobilityOptionPad1Header()
+{
+}
+
+void Ipv6MobilityOptionPad1Header::Print (std::ostream& os) const
+{
+  os << "( type=" << GetType() << ")";
+}
+
+uint32_t Ipv6MobilityOptionPad1Header::GetSerializedSize () const
+{
+  return 1;
+}
+
+void Ipv6MobilityOptionPad1Header::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+}
+
+uint32_t Ipv6MobilityOptionPad1Header::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  
+  SetType(i.ReadU8());
+  
+  return GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionPadnHeader);
+
+TypeId Ipv6MobilityOptionPadnHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionPadnHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionPadnHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionPadnHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionPadnHeader::Ipv6MobilityOptionPadnHeader(uint8_t length)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_PADN);
+  SetLength(length-2);
+}
+
+Ipv6MobilityOptionPadnHeader::~Ipv6MobilityOptionPadnHeader()
+{
+}
+
+void Ipv6MobilityOptionPadnHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << GetType() << ", length(excluding TL)=" << GetLength() <<")";
+}
+
+uint32_t Ipv6MobilityOptionPadnHeader::GetSerializedSize () const
+{
+  return GetLength() + 2;
+}
+
+void Ipv6MobilityOptionPadnHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  uint8_t len = GetLength();
+
+  i.WriteU8(GetType());
+  i.WriteU8(len);
+  
+  while(len-- > 0)
+    {
+      i.WriteU8(0);
+    }
+}
+
+uint32_t Ipv6MobilityOptionPadnHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  uint8_t len;
+  
+  SetType(i.ReadU8());
+  SetLength((len=i.ReadU8()));
+  
+  while(len-- > 0)
+    {
+	  i.ReadU8();
+	}
+	
+  return GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionMobileNodeIdentifierHeader);
+
+TypeId Ipv6MobilityOptionMobileNodeIdentifierHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionMobileNodeIdentifierHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionMobileNodeIdentifierHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionMobileNodeIdentifierHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionMobileNodeIdentifierHeader::Ipv6MobilityOptionMobileNodeIdentifierHeader()
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_MOBILE_NODE_IDENTIFIER);
+  SetLength(1);
+  SetSubtype(1);
+}
+
+Ipv6MobilityOptionMobileNodeIdentifierHeader::~Ipv6MobilityOptionMobileNodeIdentifierHeader()
+{
+}
+
+uint8_t Ipv6MobilityOptionMobileNodeIdentifierHeader::GetSubtype() const
+{
+  return m_subtype;
+}
+
+void Ipv6MobilityOptionMobileNodeIdentifierHeader::SetSubtype(uint8_t subtype)
+{
+  m_subtype = subtype;
+}
+
+Identifier Ipv6MobilityOptionMobileNodeIdentifierHeader::GetNodeIdentifier() const
+{
+  return m_nodeIdentifier;
+}
+
+void Ipv6MobilityOptionMobileNodeIdentifierHeader::SetNodeIdentifier(Identifier id)
+{
+  m_nodeIdentifier = id;
+  
+  SetLength(id.GetLength() + 1); //including subtype size
+}
+
+void Ipv6MobilityOptionMobileNodeIdentifierHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << GetType() << ", length(excluding TL)=" << GetLength() << ", subtype=" << (uint8_t)GetSubtype() << ", NodeId=" << GetNodeIdentifier() << ")";
+}
+
+uint32_t Ipv6MobilityOptionMobileNodeIdentifierHeader::GetSerializedSize () const
+{
+  return GetLength() + 2;
+}
+
+void Ipv6MobilityOptionMobileNodeIdentifierHeader::Serialize (Buffer::Iterator start) const
+{
+  uint8_t buf_id[Identifier::MAX_SIZE];
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+  i.WriteU8(GetLength());
+  
+  i.WriteU8(GetSubtype());
+  
+  m_nodeIdentifier.CopyTo(buf_id, Identifier::MAX_SIZE);
+  i.Write(buf_id, m_nodeIdentifier.GetLength());
+}
+
+uint32_t Ipv6MobilityOptionMobileNodeIdentifierHeader::Deserialize (Buffer::Iterator start)
+{
+  uint8_t buf_id[Identifier::MAX_SIZE];
+  Buffer::Iterator i = start;
+  uint8_t len;
+  
+  SetType(i.ReadU8());
+  SetLength((len=i.ReadU8()));
+  
+  SetSubtype(i.ReadU8());
+  len --;
+  
+  i.Read(buf_id, len);
+  
+  SetNodeIdentifier(Identifier(buf_id, len));
+	
+  return GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionHomeNetworkPrefixHeader);
+
+TypeId Ipv6MobilityOptionHomeNetworkPrefixHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionHomeNetworkPrefixHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionHomeNetworkPrefixHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionHomeNetworkPrefixHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionHomeNetworkPrefixHeader::Ipv6MobilityOptionHomeNetworkPrefixHeader()
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_HOME_NETWORK_PREFIX);
+  SetLength(18);
+  
+  m_reserved = 0;
+  m_prefix.Set("::");
+  m_prefixLen = 0;
+}
+
+Ipv6MobilityOptionHomeNetworkPrefixHeader::Ipv6MobilityOptionHomeNetworkPrefixHeader(Ipv6Address hnp, uint8_t plen)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_HOME_NETWORK_PREFIX);
+  SetLength(18);
+  
+  m_reserved = 0;
+  m_prefix = hnp;
+  m_prefixLen = plen;
+}
+
+Ipv6MobilityOptionHomeNetworkPrefixHeader::~Ipv6MobilityOptionHomeNetworkPrefixHeader()
+{
+}
+
+uint8_t Ipv6MobilityOptionHomeNetworkPrefixHeader::GetReserved() const
+{
+  return m_reserved;
+}
+
+void Ipv6MobilityOptionHomeNetworkPrefixHeader::SetReserved(uint8_t reserved)
+{
+  m_reserved = reserved;
+}
+  
+uint8_t Ipv6MobilityOptionHomeNetworkPrefixHeader::GetPrefixLength() const
+{
+  return m_prefixLen;
+}
+
+void Ipv6MobilityOptionHomeNetworkPrefixHeader::SetPrefixLength(uint8_t plen)
+{
+  m_prefixLen = plen;
+}
+  
+Ipv6Address Ipv6MobilityOptionHomeNetworkPrefixHeader::GetPrefix() const
+{
+  return m_prefix;
+}
+
+void Ipv6MobilityOptionHomeNetworkPrefixHeader::SetPrefix(Ipv6Address prefix)
+{
+  m_prefix = prefix;
+}
+
+void Ipv6MobilityOptionHomeNetworkPrefixHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << GetType() << ", length(excluding TL)=" << GetLength() << ", prefix_len=" << GetPrefixLength() << ", prefix=" << GetPrefix() <<")";
+}
+
+uint32_t Ipv6MobilityOptionHomeNetworkPrefixHeader::GetSerializedSize () const
+{
+  return GetLength()+2;
+}
+
+void Ipv6MobilityOptionHomeNetworkPrefixHeader::Serialize (Buffer::Iterator start) const
+{
+  uint8_t buff_prefix[16];
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+  i.WriteU8(GetLength());
+  
+  i.WriteU8(m_reserved);
+  i.WriteU8(m_prefixLen);
+  
+  m_prefix.Serialize(buff_prefix);
+  i.Write(buff_prefix, 16);
+}
+
+uint32_t Ipv6MobilityOptionHomeNetworkPrefixHeader::Deserialize (Buffer::Iterator start)
+{
+  uint8_t buff[16];
+  Buffer::Iterator i = start;
+  
+  SetType(i.ReadU8());
+  SetLength(i.ReadU8());
+  
+  m_reserved = i.ReadU8();
+  m_prefixLen = i.ReadU8();
+  
+  i.Read(buff, 16);
+  m_prefix.Set(buff);
+  
+  return GetSerializedSize();
+}
+
+Ipv6MobilityOptionHeader::Alignment Ipv6MobilityOptionHomeNetworkPrefixHeader::GetAlignment () const
+{
+  return (Alignment){6,3}; //6n+3
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionHandoffIndicatorHeader);
+
+TypeId Ipv6MobilityOptionHandoffIndicatorHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionHandoffIndicatorHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionHandoffIndicatorHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionHandoffIndicatorHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionHandoffIndicatorHeader::Ipv6MobilityOptionHandoffIndicatorHeader(uint8_t hi)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_HANDOFF_INDICATOR);
+  SetLength(2);
+  
+  m_reserved = 0;
+  m_handoffIndicator = hi;
+}
+
+Ipv6MobilityOptionHandoffIndicatorHeader::~Ipv6MobilityOptionHandoffIndicatorHeader()
+{
+}
+
+uint8_t Ipv6MobilityOptionHandoffIndicatorHeader::GetReserved() const
+{
+  return m_reserved;
+}
+
+void Ipv6MobilityOptionHandoffIndicatorHeader::SetReserved(uint8_t reserved)
+{
+  m_reserved = reserved;
+}
+
+uint8_t Ipv6MobilityOptionHandoffIndicatorHeader::GetHandoffIndicator() const
+{
+  return m_handoffIndicator;
+}
+
+void Ipv6MobilityOptionHandoffIndicatorHeader::SetHandoffIndicator(uint8_t hi)
+{
+  m_handoffIndicator = hi;
+}
+
+void Ipv6MobilityOptionHandoffIndicatorHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << (uint32_t)GetType() << ", length(excluding TL)=" << (uint32_t)GetLength() << ", handoff_indicator=" << (uint32_t)GetHandoffIndicator() << ")";
+}
+
+uint32_t Ipv6MobilityOptionHandoffIndicatorHeader::GetSerializedSize () const
+{
+  return GetLength() + 2;
+}
+
+void Ipv6MobilityOptionHandoffIndicatorHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+  i.WriteU8(GetLength());
+  
+  i.WriteU8(m_reserved);
+  i.WriteU8(m_handoffIndicator);
+}
+
+uint32_t Ipv6MobilityOptionHandoffIndicatorHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  
+  SetType(i.ReadU8());
+  SetLength(i.ReadU8());
+  
+  m_reserved = i.ReadU8();
+  m_handoffIndicator = i.ReadU8();
+  
+  return GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionAccessTechnologyTypeHeader);
+
+TypeId Ipv6MobilityOptionAccessTechnologyTypeHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionAccessTechnologyTypeHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionAccessTechnologyTypeHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionAccessTechnologyTypeHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionAccessTechnologyTypeHeader::Ipv6MobilityOptionAccessTechnologyTypeHeader()
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_ACCESS_TECHNOLOGY_TYPE);
+  SetLength(2);
+  
+  m_reserved = 0;
+  m_accessTechnologyType = Ipv6MobilityHeader::OPT_ATT_RESERVED;
+}
+
+Ipv6MobilityOptionAccessTechnologyTypeHeader::Ipv6MobilityOptionAccessTechnologyTypeHeader(uint8_t att)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_ACCESS_TECHNOLOGY_TYPE);
+  SetLength(2);
+  
+  m_reserved = 0;
+  m_accessTechnologyType = att;
+}
+
+Ipv6MobilityOptionAccessTechnologyTypeHeader::~Ipv6MobilityOptionAccessTechnologyTypeHeader()
+{
+}
+
+uint8_t Ipv6MobilityOptionAccessTechnologyTypeHeader::GetReserved() const
+{
+  return m_reserved;
+}
+
+void Ipv6MobilityOptionAccessTechnologyTypeHeader::SetReserved(uint8_t reserved)
+{
+  m_reserved = reserved;
+}
+
+uint8_t Ipv6MobilityOptionAccessTechnologyTypeHeader::GetAccessTechnologyType() const
+{
+  return m_accessTechnologyType;
+}
+
+void Ipv6MobilityOptionAccessTechnologyTypeHeader::SetAccessTechnologyType(uint8_t att)
+{
+  m_accessTechnologyType = att;
+}
+
+void Ipv6MobilityOptionAccessTechnologyTypeHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << (uint32_t)GetType() << ", length(excluding TL)=" << (uint32_t)GetLength() << ", access_technology_type=" << (uint32_t)GetAccessTechnologyType() << ")";
+}
+
+uint32_t Ipv6MobilityOptionAccessTechnologyTypeHeader::GetSerializedSize () const
+{
+  return GetLength()+2;
+}
+
+void Ipv6MobilityOptionAccessTechnologyTypeHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+  i.WriteU8(GetLength());
+  
+  i.WriteU8(m_reserved);
+  i.WriteU8(m_accessTechnologyType);
+}
+
+uint32_t Ipv6MobilityOptionAccessTechnologyTypeHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  
+  SetType(i.ReadU8());
+  SetLength(i.ReadU8());
+  
+  m_reserved = i.ReadU8();
+  m_accessTechnologyType = i.ReadU8();
+  
+  return GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader);
+
+TypeId Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader()
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_MOBILE_NODE_LINK_LAYER_IDENTIFIER);
+  SetLength(2);
+  
+  m_reserved = 0;
+}
+
+Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader(Identifier llid)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_MOBILE_NODE_LINK_LAYER_IDENTIFIER);
+  SetLength(2+llid.GetLength());
+  
+  m_reserved = 0;
+  m_linkLayerIdentifier = llid;
+}
+
+Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader(uint8_t *pllid, uint8_t len)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_MOBILE_NODE_LINK_LAYER_IDENTIFIER);
+  SetLength(2+len);
+  
+  m_reserved = 0;
+  m_linkLayerIdentifier.CopyFrom(pllid, len);
+}
+
+Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::~Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader()
+{
+}
+
+uint16_t Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::GetReserved() const
+{
+  return m_reserved;
+}
+
+void Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::SetReserved(uint16_t reserved)
+{
+  m_reserved = reserved;
+}
+
+Identifier Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::GetLinkLayerIdentifier() const
+{
+  return m_linkLayerIdentifier;
+}
+
+void Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::SetLinkLayerIdentifier(Identifier llid)
+{
+  SetLength(2 + llid.GetLength());
+  m_linkLayerIdentifier = llid;
+}
+
+void Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::SetLinkLayerIdentifier(uint8_t *pllid, uint8_t len)
+{
+  SetLength(2 + len);
+  m_linkLayerIdentifier.CopyFrom(pllid, len);
+}
+
+void Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << (uint32_t)GetType() << ", length(excluding TL)=" << (uint32_t)GetLength() << ", linkLayerIdentifier=" << GetLinkLayerIdentifier() << ")";
+}
+
+uint32_t Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::GetSerializedSize () const
+{
+  return GetLength()+2;
+}
+
+void Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::Serialize (Buffer::Iterator start) const
+{
+  uint8_t buf_llid[Identifier::MAX_SIZE];
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+  i.WriteU8(GetLength());
+  
+  i.WriteHtonU16(m_reserved);
+  
+  m_linkLayerIdentifier.CopyTo(buf_llid, Identifier::MAX_SIZE);
+  i.Write(buf_llid, m_linkLayerIdentifier.GetLength());
+}
+
+uint32_t Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::Deserialize (Buffer::Iterator start)
+{
+  uint8_t buf_llid[Identifier::MAX_SIZE];
+  Buffer::Iterator i = start;
+  uint8_t len; 
+  
+  SetType(i.ReadU8());
+  SetLength((len=i.ReadU8()));
+  
+  m_reserved = i.ReadNtohU16();
+  len -= 2; // decrease reserved size
+  i.Read(buf_llid, len);
+  m_linkLayerIdentifier.CopyFrom(buf_llid, len);
+  
+  return GetSerializedSize();
+}
+
+Ipv6MobilityOptionHeader::Alignment Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader::GetAlignment () const
+{
+  return (Alignment){2,0}; //2n
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionLinkLocalAddressHeader);
+
+TypeId Ipv6MobilityOptionLinkLocalAddressHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionLinkLocalAddressHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionLinkLocalAddressHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionLinkLocalAddressHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionLinkLocalAddressHeader::Ipv6MobilityOptionLinkLocalAddressHeader()
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_LINK_LOCAL_ADDRESS);
+  SetLength(16);
+  
+  m_linkLocalAddress.Set("::");
+}
+
+Ipv6MobilityOptionLinkLocalAddressHeader::Ipv6MobilityOptionLinkLocalAddressHeader(Ipv6Address lla)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_LINK_LOCAL_ADDRESS);
+  SetLength(16);
+  
+  m_linkLocalAddress = lla;
+}
+
+Ipv6MobilityOptionLinkLocalAddressHeader::~Ipv6MobilityOptionLinkLocalAddressHeader()
+{
+}
+
+Ipv6Address Ipv6MobilityOptionLinkLocalAddressHeader::GetLinkLocalAddress() const
+{
+  return m_linkLocalAddress;
+}
+
+void Ipv6MobilityOptionLinkLocalAddressHeader::SetLinkLocalAddress(Ipv6Address lla)
+{
+  m_linkLocalAddress = lla;
+}
+
+void Ipv6MobilityOptionLinkLocalAddressHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << (uint32_t)GetType() << ", length(excluding TL)=" << (uint32_t)GetLength() << ", link_local_address=" << GetLinkLocalAddress() << ")";
+}
+
+uint32_t Ipv6MobilityOptionLinkLocalAddressHeader::GetSerializedSize () const
+{
+  return GetLength()+2;
+}
+
+void Ipv6MobilityOptionLinkLocalAddressHeader::Serialize (Buffer::Iterator start) const
+{
+  uint8_t buf_lla[16];
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+  i.WriteU8(GetLength());
+
+  m_linkLocalAddress.Serialize(buf_lla);
+  i.Write(buf_lla, 16);  
+}
+
+uint32_t Ipv6MobilityOptionLinkLocalAddressHeader::Deserialize (Buffer::Iterator start)
+{
+  uint8_t buf_lla[16];
+  Buffer::Iterator i = start;
+  
+  SetType(i.ReadU8());
+  SetLength(i.ReadU8());
+  
+  i.Read(buf_lla, 16);
+  m_linkLocalAddress.Set(buf_lla);
+  
+  return GetSerializedSize();
+}
+
+Ipv6MobilityOptionHeader::Alignment Ipv6MobilityOptionLinkLocalAddressHeader::GetAlignment () const
+{
+  return (Alignment){8,6}; //8n+6
+}
+
+NS_OBJECT_ENSURE_REGISTERED(Ipv6MobilityOptionTimestampHeader);
+
+TypeId Ipv6MobilityOptionTimestampHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6MobilityOptionTimestampHeader")
+    .SetParent<Ipv6MobilityOptionHeader> ()
+    .AddConstructor<Ipv6MobilityOptionTimestampHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Ipv6MobilityOptionTimestampHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Ipv6MobilityOptionTimestampHeader::Ipv6MobilityOptionTimestampHeader()
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_TIMESTAMP);
+  SetLength(8);
+  
+  SetTimestamp(Simulator::Now());
+}
+
+Ipv6MobilityOptionTimestampHeader::Ipv6MobilityOptionTimestampHeader(Time timestamp)
+{
+  SetType(Ipv6MobilityHeader::IPV6_MOBILITY_OPT_TIMESTAMP);
+  SetLength(8);
+  
+  SetTimestamp(timestamp);
+}
+
+Ipv6MobilityOptionTimestampHeader::~Ipv6MobilityOptionTimestampHeader()
+{
+}
+
+Time Ipv6MobilityOptionTimestampHeader::GetTimestamp() const
+{
+  return m_timestamp;
+}
+
+void Ipv6MobilityOptionTimestampHeader::SetTimestamp(Time timestamp)
+{
+  m_timestamp = timestamp;
+}
+
+void Ipv6MobilityOptionTimestampHeader::Print (std::ostream& os) const
+{
+  os << "( type=" << (uint32_t)GetType() << ", length(excluding TL)=" << (uint32_t)GetLength() << ", timestamp=" << m_timestamp.GetSeconds() << "(s))";
+}
+
+uint32_t Ipv6MobilityOptionTimestampHeader::GetSerializedSize () const
+{
+  return GetLength()+2;
+}
+
+void Ipv6MobilityOptionTimestampHeader::Serialize (Buffer::Iterator start) const
+{
+  uint64_t timestamp;
+  Buffer::Iterator i = start;
+
+  i.WriteU8(GetType());
+  i.WriteU8(GetLength());
+
+  timestamp = m_timestamp.GetMicroSeconds();
+  
+  i.WriteHtonU64(timestamp);
+}
+
+uint32_t Ipv6MobilityOptionTimestampHeader::Deserialize (Buffer::Iterator start)
+{
+  uint64_t timestamp;
+  Buffer::Iterator i = start;
+  
+  SetType(i.ReadU8());
+  SetLength(i.ReadU8());
+  
+  timestamp = i.ReadNtohU64();
+  m_timestamp = MicroSeconds (timestamp);
+  
+  return GetSerializedSize();
+}
+
+Ipv6MobilityOptionHeader::Alignment Ipv6MobilityOptionTimestampHeader::GetAlignment () const
+{
+  return (Alignment){8,6}; //8n+6
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-mobility-option-header.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,404 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_MOBILITY_OPTION_HEADER_H
+#define IPV6_MOBILITY_OPTION_HEADER_H
+
+#include <list>
+
+#include "ns3/header.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/identifier.h"
+
+namespace ns3
+{
+
+/**
+ * \class Ipv6MobilityOptionHeader
+ * \brief Ipv6 Mobility option header.
+ */
+class Ipv6MobilityOptionHeader : public Header
+{
+public:
+  /**
+   * \struct Alignment
+   * \brief represents the alignment requirements of an option header
+   *
+   * Represented ad facter*n+offset (eg. 8n+2) See RFC 2460.
+   * No alignment is represented as 1n+0
+   */
+   struct Alignment
+   {
+     uint8_t factor;
+	 uint8_t offset;
+   };
+  
+  /**
+   * \brief Get the UID of this class.
+   * \return UID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief Get the instance type ID.
+   * \return instance type ID
+   */
+  virtual TypeId GetInstanceTypeId () const;
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6MobilityOptionHeader ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6MobilityOptionHeader ();
+
+  /**
+   * \brief Get the type of the option.
+   * \return type
+   */
+  uint8_t GetType () const;
+
+  /**
+   * \brief Set the type of the option.
+   * \param type the type to set
+   */
+  void SetType (uint8_t type);
+
+  /**
+   * \brief Get the length of the option in 8 bytes unit.
+   * \return length of the option
+   */
+  uint8_t GetLength () const;
+
+  /**
+   * \brief Set the length of the option.
+   * \param len length value to set
+   */
+  void SetLength (uint8_t len);
+
+  /**
+   * \brief Print informations.
+   * \param os output stream
+   */
+  virtual void Print (std::ostream& os) const;
+
+  /**
+   * \brief Get the serialized size.
+   * \return serialized size
+   */
+  virtual uint32_t GetSerializedSize () const;
+
+  /**
+   * \brief Serialize the packet.
+   * \param start start offset
+   */
+  virtual void Serialize (Buffer::Iterator start) const;
+
+  /**
+   * \brief Deserialize the packet.
+   * \param start start offset
+   * \return length of packet
+   */
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  
+  /**
+   * \brief Get the Alignment requirement of this option header
+   * \return the required alignment
+   *
+   * Subclasses should only implement this method, if special alignment is
+   * required. Default is no alignment (1n+0)
+   */
+  virtual Alignment GetAlignment () const;
+
+private:
+  /**
+   * \brief The type.
+   */
+  uint8_t m_type;
+
+  /**
+   * \brief The length.
+   */
+  uint8_t m_len;
+};
+
+class Ipv6MobilityOptionPad1Header : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionPad1Header();
+  
+  virtual ~Ipv6MobilityOptionPad1Header();
+
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  
+protected:
+
+private:
+
+};
+
+class Ipv6MobilityOptionPadnHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionPadnHeader( uint8_t length = 2 );
+  
+  virtual ~Ipv6MobilityOptionPadnHeader();
+
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+ 
+protected:
+
+private:
+
+};
+
+class Ipv6MobilityOptionMobileNodeIdentifierHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionMobileNodeIdentifierHeader();
+  
+  virtual ~Ipv6MobilityOptionMobileNodeIdentifierHeader();
+  
+  uint8_t GetSubtype() const;
+  void SetSubtype(uint8_t subtype);
+  
+  Identifier GetNodeIdentifier() const;
+  void SetNodeIdentifier(Identifier id);
+
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+ 
+protected:
+
+private:
+  uint8_t m_subtype;
+  Identifier m_nodeIdentifier;
+};
+
+class Ipv6MobilityOptionHomeNetworkPrefixHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionHomeNetworkPrefixHeader();
+  Ipv6MobilityOptionHomeNetworkPrefixHeader(Ipv6Address prefix, uint8_t plen);
+  
+  virtual ~Ipv6MobilityOptionHomeNetworkPrefixHeader();
+  
+  uint8_t GetReserved() const;
+  void SetReserved(uint8_t reserved);
+  
+  uint8_t GetPrefixLength() const;
+  void SetPrefixLength(uint8_t plen);
+  
+  Ipv6Address GetPrefix() const;
+  void SetPrefix(Ipv6Address prefix);
+
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  virtual Alignment GetAlignment () const;
+  
+protected:
+
+private:
+  uint8_t m_reserved;
+  uint8_t m_prefixLen;
+  Ipv6Address m_prefix;
+};
+
+class Ipv6MobilityOptionHandoffIndicatorHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionHandoffIndicatorHeader(uint8_t hi = 4);
+  
+  virtual ~Ipv6MobilityOptionHandoffIndicatorHeader();
+  
+  uint8_t GetReserved() const;
+  void SetReserved(uint8_t reserved);
+  
+  uint8_t GetHandoffIndicator() const;
+  void SetHandoffIndicator(uint8_t hi);
+
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  
+protected:
+
+private:
+  uint8_t m_reserved;
+  uint8_t m_handoffIndicator;
+
+};
+
+class Ipv6MobilityOptionAccessTechnologyTypeHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionAccessTechnologyTypeHeader();
+  Ipv6MobilityOptionAccessTechnologyTypeHeader(uint8_t att);
+  
+  virtual ~Ipv6MobilityOptionAccessTechnologyTypeHeader();
+  
+  uint8_t GetReserved() const;
+  void SetReserved(uint8_t reserved);
+  
+  uint8_t GetAccessTechnologyType (void) const;
+  void SetAccessTechnologyType (uint8_t att);
+
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  
+protected:
+
+private:
+  uint8_t m_reserved;
+  uint8_t m_accessTechnologyType;
+};
+
+class Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader();
+  Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader(Identifier llid);
+  Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader(uint8_t *pllid, uint8_t len);
+  
+  virtual ~Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader();
+
+  uint16_t GetReserved() const;
+  void SetReserved(uint16_t reserved);
+  
+  Identifier GetLinkLayerIdentifier() const;
+  void SetLinkLayerIdentifier(Identifier llid);
+  void SetLinkLayerIdentifier(uint8_t *pllid, uint8_t len);
+  
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  virtual Alignment GetAlignment () const;
+  
+protected:
+
+private:
+  uint16_t m_reserved;
+  Identifier m_linkLayerIdentifier;
+};
+
+class Ipv6MobilityOptionLinkLocalAddressHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionLinkLocalAddressHeader();
+  Ipv6MobilityOptionLinkLocalAddressHeader(Ipv6Address lla);
+  
+  virtual ~Ipv6MobilityOptionLinkLocalAddressHeader();
+  
+  Ipv6Address GetLinkLocalAddress (void) const;
+  
+  void SetLinkLocalAddress(Ipv6Address lla);
+
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  virtual Alignment GetAlignment () const;
+  
+protected:
+
+private:
+  Ipv6Address m_linkLocalAddress;
+};
+
+class Ipv6MobilityOptionTimestampHeader : public Ipv6MobilityOptionHeader
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Ipv6MobilityOptionTimestampHeader();
+  Ipv6MobilityOptionTimestampHeader(Time timestamp);
+  
+  virtual ~Ipv6MobilityOptionTimestampHeader();
+
+  Time GetTimestamp() const;
+  void SetTimestamp(Time timestamp);
+  
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+  virtual Alignment GetAlignment () const;
+ 
+protected:
+
+private:
+  /**
+    * higher 48bits: seconds since 1970/01/01 00:00:00
+	* lower  16bits: 1/65536 fractions of a second
+	*/
+  Time m_timestamp;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_MOBILITY_OPTION_HEADER_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.cc	2014-01-26 16:08:02.000000000 +0100
@@ -0,0 +1,416 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+#include <iomanip>
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/net-device.h"
+#include "ns3/names.h"
+
+#include "ns3/ipv6-routing-table-entry.h"
+
+#include "ipv6-static-source-routing.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6StaticSourceRouting");
+
+TypeId Ipv6StaticSourceRouting::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6StaticSourceRouting")
+    .SetParent<Ipv6RoutingProtocol> ()
+    .AddConstructor<Ipv6StaticSourceRouting> ()
+    ;
+  return tid;
+}
+
+Ipv6StaticSourceRouting::Ipv6StaticSourceRouting ()
+  : m_ipv6 (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6StaticSourceRouting::~Ipv6StaticSourceRouting ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6StaticSourceRouting::SetIpv6 (Ptr<Ipv6> ipv6)
+{
+  NS_LOG_FUNCTION (this << ipv6);
+  NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
+  uint32_t i = 0; 
+  m_ipv6 = ipv6;
+
+  for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
+    {
+      if (m_ipv6->IsUp (i))
+        {
+          NotifyInterfaceUp (i);
+        }
+      else
+        {
+          NotifyInterfaceDown (i);
+        }
+    }
+}
+
+void Ipv6StaticSourceRouting::AddHostRouteFrom (Ipv6Address src, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << src << nextHop << interface << prefixToUse << metric);
+  if (nextHop.IsLinkLocal())
+    {
+      NS_LOG_WARN ("Ipv6StaticSourceRouting::AddHostRouteFrom - Next hop should be link-local");
+    }
+AddNetworkRouteFrom (src, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
+}
+
+void Ipv6StaticSourceRouting::AddHostRouteFrom (Ipv6Address src, uint32_t interface, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << src << interface << metric);
+  AddNetworkRouteFrom (src, Ipv6Prefix::GetOnes (), interface, metric);
+}
+
+void Ipv6StaticSourceRouting::AddNetworkRouteFrom (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
+  if (nextHop.IsLinkLocal())
+    {
+      NS_LOG_WARN ("Ipv6StaticSourceRouting::AddNetworkRouteFrom - Next hop should be link-local");
+    }
+Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
+  m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticSourceRouting::AddNetworkRouteFrom (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
+  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
+  m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+void Ipv6StaticSourceRouting::AddNetworkRouteFrom (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
+{
+  NS_LOG_FUNCTION (this << network << networkPrefix << interface);
+  Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
+  *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
+  m_networkRoutes.push_back (std::make_pair (route, metric));
+}
+
+Ptr<Ipv6Route> Ipv6StaticSourceRouting::LookupStatic (Ipv6Address src, Ipv6Address dst)
+{
+  NS_LOG_FUNCTION (this << src << dst);
+  Ptr<Ipv6Route> rtentry = 0;
+  uint16_t longestMask = 0;
+  uint32_t shortestMetric = 0xffffffff;
+
+  /* when sending on link-local multicast, there have to be interface specified */
+  if (src == Ipv6Address::GetAllNodesMulticast () || src.IsSolicitedMulticast () || 
+      src == Ipv6Address::GetAllRoutersMulticast () || src == Ipv6Address::GetAllHostsMulticast ())
+    {
+      return 0;
+    }
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      Ipv6RoutingTableEntry* j = it->first;
+      uint32_t metric = it->second;
+      Ipv6Prefix mask = j->GetDestNetworkPrefix ();
+      uint16_t maskLen = mask.GetPrefixLength ();
+      Ipv6Address entry = j->GetDestNetwork ();
+
+      NS_LOG_LOGIC ("Searching for route from " << src << ", mask length " << maskLen << ", metric " << metric);
+
+      if (mask.IsMatch (src, entry))
+        {
+          NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
+
+		  if (maskLen < longestMask)
+			{
+			  NS_LOG_LOGIC ("Previous match longer, skipping");
+			  continue;
+			}
+
+		  if (maskLen > longestMask)
+			{
+			  shortestMetric = 0xffffffff;
+			}
+
+		  longestMask = maskLen;
+		  if (metric > shortestMetric)
+			{
+			  NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
+			  continue;
+			}
+
+		  shortestMetric = metric;
+		  Ipv6RoutingTableEntry* route = j;
+		  uint32_t interfaceIdx = route->GetInterface ();
+		  rtentry = Create<Ipv6Route> ();
+
+		  rtentry->SetSource (route->GetDest());
+		  rtentry->SetDestination (dst);
+		  rtentry->SetGateway (route->GetGateway ());
+		  rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
+        }
+    }
+
+  if(rtentry)
+    {
+      NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
+    }
+  return rtentry;
+}
+
+void Ipv6StaticSourceRouting::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (NetworkRoutesI j = m_networkRoutes.begin () ;  j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
+    {
+      delete j->first;
+    }
+  m_networkRoutes.clear ();
+
+  m_ipv6 = 0;
+  Ipv6RoutingProtocol::DoDispose ();
+}
+
+uint32_t Ipv6StaticSourceRouting::GetNRoutes () const
+{
+  return m_networkRoutes.size ();
+}
+
+Ipv6RoutingTableEntry Ipv6StaticSourceRouting::GetRoute (uint32_t index) const
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+
+  for (NetworkRoutesCI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      if (tmp == index)
+        {
+          return it->first;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+
+uint32_t Ipv6StaticSourceRouting::GetMetric (uint32_t index) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  uint32_t tmp = 0;
+
+  for (NetworkRoutesCI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      if (tmp == index)
+        {
+          return it->second;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+  // quiet compiler.
+  return 0;
+}
+
+void Ipv6StaticSourceRouting::RemoveRoute (uint32_t index)
+{
+  NS_LOG_FUNCTION (this << index);
+  uint32_t tmp = 0;
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      if (tmp == index)
+        {
+          delete it->first;
+          m_networkRoutes.erase (it);
+          return;
+        }
+      tmp++;
+    }
+  NS_ASSERT (false);
+}
+
+void Ipv6StaticSourceRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
+{
+  NS_LOG_FUNCTION (this << network << prefix << ifIndex);
+
+  for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
+    {
+      Ipv6RoutingTableEntry* rtentry = it->first;
+      if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex && 
+          rtentry->GetPrefixToUse () == prefixToUse)
+        {
+          delete it->first;
+          m_networkRoutes.erase (it);
+          return;
+        }
+    }
+}
+
+Ptr<Ipv6Route> Ipv6StaticSourceRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+  NS_LOG_FUNCTION (this << header << oif);
+  Ipv6Address src = header.GetSourceAddress ();
+  Ipv6Address dst = header.GetDestinationAddress ();
+  Ptr<Ipv6Route> rtentry = 0;
+  
+  if( src.IsAny() )
+    {
+	  NS_LOG_LOGIC("Source Address is ZERO, Nothing related with source routing");
+	  sockerr = Socket::ERROR_NOTERROR;
+	  return 0;
+	}
+
+  rtentry = LookupStatic (src, dst);
+  if (rtentry)
+    {
+      sockerr = Socket::ERROR_NOTERROR;
+    }
+  else
+    {
+      sockerr = Socket::ERROR_NOROUTETOHOST;
+    }
+  return rtentry;
+}
+
+bool Ipv6StaticSourceRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+                                    UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                                    LocalDeliverCallback lcb, ErrorCallback ecb)
+{
+  NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev);
+  NS_ASSERT (m_ipv6 != 0);
+  // Check if input device supports IP
+  NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0);
+  uint32_t iif = m_ipv6->GetInterfaceForDevice (idev);
+  Ipv6Address src = header.GetSourceAddress();
+  Ipv6Address dst = header.GetDestinationAddress ();
+
+  // TODO:  Configurable option to enable RFC 1222 Strong End System Model
+  // Right now, we will be permissive and allow a source to send us
+  // a packet to one of our other interface addresses; that is, the
+  // destination unicast address does not match one of the iif addresses,
+  // but we check our other interfaces.  This could be an option
+  // (to remove the outer loop immediately below and just check iif).
+  for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++)
+    {
+      for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++)
+        {
+          Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i);
+          Ipv6Address addr = iaddr.GetAddress ();
+          if (addr.IsEqual (dst))
+            {
+              if (j == iif)
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match)");
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << dst );
+                }
+              lcb (p, header, iif);
+              return true;
+            }
+          NS_LOG_LOGIC ("Address "<< addr << " not a match");
+        }
+    }
+  // Check if input device supports IP forwarding
+  if (m_ipv6->IsForwarding (iif) == false)
+    {
+      NS_LOG_LOGIC ("Forwarding disabled for this interface");
+      ecb (p, header, Socket::ERROR_NOROUTETOHOST);
+      return false;
+    }
+  // Next, try to find a route
+  Ptr<Ipv6Route> rtentry = LookupStatic (src, dst);
+
+  if (rtentry != 0)
+    {
+      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+      ucb (idev, rtentry, p, header);  // unicast forwarding callback
+      return true;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+      return false; // Let other routing protocols try to handle this
+    }
+}
+
+void Ipv6StaticSourceRouting::NotifyInterfaceUp (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+}
+
+void Ipv6StaticSourceRouting::NotifyInterfaceDown (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  uint32_t j = 0;
+  uint32_t max = GetNRoutes ();
+
+  /* remove all static routes that are going through this interface */
+  while (j < max)
+    {
+      Ipv6RoutingTableEntry route = GetRoute (j);
+
+      if (route.GetInterface () == i)
+        {
+          RemoveRoute (j);
+        }
+      else
+        {
+          j++;
+        }
+    }
+}
+
+void Ipv6StaticSourceRouting::NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+}
+
+void Ipv6StaticSourceRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address)
+{
+}
+
+void Ipv6StaticSourceRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
+}
+
+void Ipv6StaticSourceRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
+{
+  NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
+}
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-static-source-routing.h	2014-02-03 22:53:06.000000000 +0100
@@ -0,0 +1,217 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_STATIC_SOURCE_ROUTING_H
+#define IPV6_STATIC_SOURCE_ROUTING_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/ptr.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/ipv6-routing-protocol.h"
+
+namespace ns3
+{
+
+class Packet;
+class NetDevice;
+class Ipv6Interface;
+class Ipv6Route;
+class Node;
+class Ipv6RoutingTableEntry;
+class Ipv6MulticastRoutingTableEntry;
+
+/**
+ * \ingroup routing
+ * \defgroup Ipv6StaticSourceRouting Ipv6StaticSourceRouting
+ */
+/**
+ * \ingroup Ipv6StaticSourceRouting
+ * \class Ipv6StaticSourceRouting
+ * \brief Static routing protocol for IP version 6 stack.
+ * \see Ipv6RoutingProtocol
+ * \see Ipv6ListRouting
+ */
+class Ipv6StaticSourceRouting : public Ipv6RoutingProtocol
+{
+public:
+  /**
+   * \brief The interface Id associated with this class.
+   * \return type identifier
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6StaticSourceRouting ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6StaticSourceRouting ();
+
+  /**
+   * \brief Add route to host.
+   * \param dest destination address
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param prefixToUse prefix that should be used for source address for this destination
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddHostRouteFrom (Ipv6Address src, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
+
+  /**
+   * \brief Add route to host.
+   * \param dest destination address.
+   * \param interface interface index
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddHostRouteFrom (Ipv6Address src, uint32_t interface, uint32_t metric = 0);
+
+  /**
+   * \brief Add route to network.
+   * \param network network address
+   * \param networkPrefix network prefix*
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddNetworkRouteFrom (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric = 0);
+
+  /**
+   * \brief Add route to network.
+   * \param network network address
+   * \param networkPrefix network prefix*
+   * \param nextHop next hop address to route the packet
+   * \param interface interface index
+   * \param prefixToUse prefix that should be used for source address for this destination
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddNetworkRouteFrom (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric = 0);
+
+  /**
+   * \brief Add route to network.
+   * \param network network address
+   * \param networkPrefix network prefix
+   * \param interface interface index
+   * \param metric metric of route in case of multiple routes to same destination
+   */
+  void AddNetworkRouteFrom (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric = 0);
+
+  /**
+   * \brief Get the number or entries in the routing table.
+   * \return number of entries
+   */
+  uint32_t GetNRoutes () const;
+
+  /**
+   * \brief Get a specified route.
+   * \param i index
+   * \return the route whose index is i
+   */
+  Ipv6RoutingTableEntry GetRoute (uint32_t i) const;
+
+  /**
+   * \brief Get a metric for route from the static unicast routing table.
+   * \param index The index (into the routing table) of the route to retrieve.  
+   * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
+   */
+  uint32_t GetMetric (uint32_t index) const;
+
+  /**
+   * \brief Remove a route from the routing table.
+   * \param i index
+   */
+  void RemoveRoute (uint32_t i);
+
+  /**
+   * \brief Remove a route from the routing table.
+   * \param network IPv6 network
+   * \param prefix IPv6 prefix
+   * \param ifIndex interface index
+   * \param prefixToUse IPv6 prefix to use with this route (multihoming)
+   */
+  void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse);
+
+  virtual Ptr<Ipv6Route> RouteOutput (Ptr<Packet> p, const Ipv6Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr);
+
+  virtual bool RouteInput  (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> idev,
+                            UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                            LocalDeliverCallback lcb, ErrorCallback ecb);
+
+  virtual void NotifyInterfaceUp (uint32_t interface);
+  virtual void NotifyInterfaceDown (uint32_t interface);
+  virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
+  virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
+  virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+  virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
+  virtual void SetIpv6 (Ptr<Ipv6> ipv6);
+
+  /**
+   * \brief Print the Routing Table entries
+   *
+   * \param stream the ostream the Routing table is printed to
+   */
+
+  virtual void PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const {};
+protected:
+  /**
+   * \brief Dispose this object.
+   */
+  virtual void DoDispose ();
+
+private:
+  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
+  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
+  typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
+
+  /**
+   * \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 src, Ipv6Address dst);
+
+
+  /**
+   * \brief the forwarding table for network.
+   */
+  NetworkRoutes m_networkRoutes;
+
+  /**
+   * \brief Ipv6 reference.
+   */
+  Ptr<Ipv6> m_ipv6;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_STATIC_SOURCE_ROUTING_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.cc	2014-02-03 20:55:09.000000000 +0100
@@ -0,0 +1,350 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include <stdio.h>
+#include <sstream>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/boolean.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/identifier.h"
+#include "ns3/virtual-net-device.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/ipv6-interface.h"
+
+#include "ns3/ipv6-static-routing-helper.h"
+#include "ns3/ipv6-static-routing.h"
+
+#include "ipv6-tunnel-l4-protocol.h"
+
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("Ipv6TunnelL4Protocol");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv6TunnelL4Protocol);
+
+const uint8_t Ipv6TunnelL4Protocol::PROT_NUMBER = 41; /* IPV6-in-IPv6 */
+
+TypeId Ipv6TunnelL4Protocol::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Ipv6TunnelL4Protocol")
+    .SetParent<Ipv6L4Protocol> ()
+    .AddConstructor<Ipv6TunnelL4Protocol> ()
+    ;
+  return tid;
+}
+
+Ipv6TunnelL4Protocol::Ipv6TunnelL4Protocol ()
+  : m_node (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Ipv6TunnelL4Protocol::~Ipv6TunnelL4Protocol ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Ipv6TunnelL4Protocol::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_node = 0;
+  
+  for ( TunnelMapI i = m_tunnelMap.begin(); i != m_tunnelMap.end(); i++ )
+    {
+	  i->second = 0;
+	}
+	
+  m_tunnelMap.clear();
+  
+  Ipv6L4Protocol::DoDispose ();
+
+}
+
+void Ipv6TunnelL4Protocol::NotifyNewAggregate ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (m_node == 0)
+    {
+      Ptr<Node> node = this->GetObject<Node> ();
+      if (node != 0)
+        {
+          Ptr<Ipv6L3Protocol> ipv6 = this->GetObject<Ipv6L3Protocol> ();
+          if (ipv6 != 0)
+            {
+              this->SetNode (node);
+              ipv6->Insert (this);
+            }
+        }
+    }
+  Ipv6L4Protocol::NotifyNewAggregate ();
+}
+
+void Ipv6TunnelL4Protocol::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (this << node);
+  m_node = node;
+}
+
+Ptr<Node> Ipv6TunnelL4Protocol::GetNode (void)
+{
+  NS_LOG_FUNCTION_NOARGS();
+  return m_node;
+}
+
+int Ipv6TunnelL4Protocol::GetProtocolNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return PROT_NUMBER;
+}
+
+void Ipv6TunnelL4Protocol::SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
+{
+  NS_LOG_FUNCTION (this << packet << src << dst << (uint32_t)ttl);
+  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+  SocketIpTtlTag tag;
+  NS_ASSERT (ipv6 != 0);
+
+  tag.SetTtl (ttl);
+  packet->AddPacketTag (tag);
+  ipv6->Send (packet, src, dst, PROT_NUMBER, 0);
+}
+enum Ipv6L4Protocol::RxStatus_e Ipv6TunnelL4Protocol::Receive (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << header);
+  return IpL4Protocol::RX_ENDPOINT_UNREACH;
+}
+
+enum IpL4Protocol::RxStatus Ipv6TunnelL4Protocol::Receive (Ptr<Packet> packet, Ipv6Header const &header, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << header.GetSourceAddress () << header.GetDestinationAddress () << interface);
+  
+  Ptr<Ipv6L3Protocol> ipv6 = GetNode()->GetObject<Ipv6L3Protocol>();
+  NS_ASSERT (ipv6 != 0);
+  
+  /**
+   * Check whether the packet belongs to one of tunnels
+   */
+  Ptr<TunnelNetDevice> tdev = GetTunnelDevice (header.GetSourceAddress ());   
+  if (tdev == 0)
+    {
+      NS_LOG_DEBUG ("The packet does not associate any tunnel device");
+          return Ipv6L4Protocol::RX_OK;
+    }
+  
+  Ptr<Packet> p = packet->Copy();
+  
+  Ipv6Header innerHeader;
+  p->RemoveHeader(innerHeader);
+  
+  Ipv6Address source = innerHeader.GetSourceAddress();
+  Ipv6Address destination = innerHeader.GetDestinationAddress();
+  
+  if (source.IsLinkLocal() ||
+      destination.IsLinkLocal() ||
+      destination.IsAllNodesMulticast() ||
+      destination.IsAllRoutersMulticast() ||
+      destination.IsAllHostsMulticast() ||
+      destination.IsSolicitedMulticast())
+	{
+            return Ipv6L4Protocol::RX_OK;
+	}
+  
+  SocketIpTtlTag tag;
+
+  tag.SetTtl (innerHeader.GetHopLimit() - 1);
+  p->AddPacketTag (tag);
+  
+  //Prevent infinite loop
+  Ptr<Ipv6Route> route;
+  Socket::SocketErrno err;
+  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
+  
+  Ipv6StaticRoutingHelper routingHelper;
+  
+  Ptr<Ipv6StaticRouting> routing = routingHelper.GetStaticRouting (ipv6);
+  
+  NS_ASSERT (routing);
+  
+  route = routing->RouteOutput (p, innerHeader, oif, err);
+  
+  ipv6->Send(p, source, destination, innerHeader.GetNextHeader(), route);
+
+  return Ipv6L4Protocol::RX_OK;
+}
+
+uint16_t Ipv6TunnelL4Protocol::AddTunnel(Ipv6Address remote, Ipv6Address local)
+{
+  NS_LOG_FUNCTION (this << remote << local);
+  
+  //Search existing tunnel device
+  TunnelMapI it = m_tunnelMap.find (remote);
+  Ptr<TunnelNetDevice> dev = 0;
+  
+  if (it == m_tunnelMap.end ())
+    {
+      dev = CreateObject<TunnelNetDevice> ();
+      dev->SetAddress (Mac48Address::Allocate ());
+      m_node->AddDevice (dev);
+      m_tunnelMap.insert (std::pair<Ipv6Address, Ptr<TunnelNetDevice> > (remote, dev));
+      
+	  dev->SetRemoteAddress(remote);
+	  dev->SetLocalAddress(local);
+    }
+  else
+    {
+      dev = it->second;
+    }
+    
+  dev->IncreaseRefCount ();
+	
+  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
+  int32_t ifIndex = -1;
+  
+  ifIndex = ipv6->GetInterfaceForDevice (dev);
+  
+  if (ifIndex == -1)
+    {
+	  ifIndex = ipv6->AddInterface (dev);
+	  
+	  NS_ASSERT_MSG (ifIndex >= 0, "Cannot add an IPv6 interface");
+	  
+	  ipv6->SetMetric (ifIndex, 1);
+	  ipv6->SetUp (ifIndex);
+	}
+	
+  return ifIndex;
+}
+
+void Ipv6TunnelL4Protocol::RemoveTunnel(Ipv6Address remote)
+{
+  NS_LOG_FUNCTION ( this << remote );
+  
+  Ptr<TunnelNetDevice> dev = GetTunnelDevice(remote);
+
+  if (dev)
+    {
+	  dev->DecreaseRefCount ();
+	  
+	  if (dev->GetRefCount() == 0)
+	    {
+		  TunnelMapI it = m_tunnelMap.find (remote);
+          
+          it->second = 0;
+          
+          m_tunnelMap.erase (it);
+		}
+	}
+}
+
+uint16_t  Ipv6TunnelL4Protocol::ModifyTunnel(Ipv6Address remote, Ipv6Address newRemote, Ipv6Address local)
+{
+  NS_LOG_FUNCTION ( this << remote << newRemote << local );
+  
+  Ptr<TunnelNetDevice> dev = GetTunnelDevice(remote);
+  NS_ASSERT (dev != 0);
+  NS_ASSERT (dev->GetRefCount() > 0);
+	  
+  RemoveTunnel (remote);
+  return AddTunnel (newRemote, local);
+}
+
+Ptr<TunnelNetDevice> Ipv6TunnelL4Protocol::GetTunnelDevice(Ipv6Address remote)
+{
+  NS_LOG_FUNCTION ( this << remote );
+  
+  TunnelMapI it = m_tunnelMap.find (remote);
+  
+  if (it != m_tunnelMap.end ())
+    {
+      return it->second;
+    }
+
+  return 0;
+}
+
+  
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.h ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/ipv6-tunnel-l4-protocol.h	2014-02-03 20:32:27.000000000 +0100
@@ -0,0 +1,175 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef IPV6_TUNNEL_L4_PROTOCOL_H
+#define IPV6_TUNNEL_L4_PROTOCOL_H
+
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-l4-protocol.h"
+
+namespace ns3
+{
+
+class Node;
+class Packet;
+
+/**
+ * \class Ipv6TunnelL4Protocol
+ * \brief An implementation of the Ipv6 Tunnel protocol.
+ */
+class Ipv6TunnelL4Protocol : public IpL4Protocol
+{
+public:
+  /**
+   * \brief Interface ID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief IPv6 Mobility protocol number (135).
+   */
+  static const uint8_t PROT_NUMBER;
+  
+  /**
+   * \brief Get PMIPv6 protocol number.
+   * \return protocol number
+   */
+  static uint16_t GetStaticProtocolNumber ();
+
+  /**
+   * \brief Constructor.
+   */
+  Ipv6TunnelL4Protocol ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Ipv6TunnelL4Protocol ();
+
+  /**
+   * \brief Set the node.
+   * \param node the node to set
+   */
+  void SetNode (Ptr<Node> node);
+  
+  /**
+   * \brief Get the node.
+   * \return node
+   */
+  Ptr<Node> GetNode (void);
+
+    /**
+   * \brief This method is called by AddAgregate and completes the aggregation
+   * by setting the node in the Ipv6 Mobility stack.
+   */
+  virtual void NotifyNewAggregate ();
+
+  /**
+   * \brief Get the protocol number.
+   * \return protocol number
+   */
+  virtual int GetProtocolNumber () const;
+
+  /**
+   * \brief Send a packet via IPv6 Mobility, note that packet already contains IPv6 Mobility header.
+   * \param packet the packet to send which contains IPv6 Mobility header
+   * \param src source address
+   * \param dst destination address
+   * \param ttl next hop limit
+   */
+  void SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl);
+  /**
+   * \brief Receive method.
+   * \param p the packet
+   * \param src source address
+   * \param dst destination address
+   * \param interface the interface from which the packet is coming
+   */
+  virtual enum Ipv6L4Protocol::RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+
+
+  uint16_t AddTunnel(Ipv6Address remote, Ipv6Address local=Ipv6Address::GetZero());
+  void RemoveTunnel(Ipv6Address remote);
+  uint16_t ModifyTunnel(Ipv6Address remote, Ipv6Address newRemote, Ipv6Address local=Ipv6Address::GetZero());
+  Ptr<TunnelNetDevice> GetTunnelDevice(Ipv6Address remote);
+  
+protected:
+ 
+  /**
+   * \brief Dispose this object.
+   */
+  virtual void DoDispose ();
+  
+private:
+  typedef std::map<Ipv6Address, Ptr<TunnelNetDevice> > TunnelMap;
+  typedef std::map<Ipv6Address, Ptr<TunnelNetDevice> >::iterator TunnelMapI;
+  
+  /**
+   * \brief The node.
+   */
+  Ptr<Node> m_node;
+  
+  TunnelMap m_tunnelMap;
+};
+
+} /* namespace ns3 */
+
+#endif /* IPV6_TUNNEL_L4_PROTOCOL_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,184 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+ 
+#include <stdio.h>
+#include <sstream>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/node.h"
+#include "ns3/packet.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-interface.h"
+
+#include "pmipv6-profile.h"
+#include "ipv6-mobility-header.h"
+#include "pmipv6-agent.h"
+
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("Pmipv6Agent");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Pmipv6Agent);
+
+TypeId Pmipv6Agent::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Pmipv6Agent")
+    .SetParent<Object> ()
+    .AddConstructor<Pmipv6Agent> ()
+    ;
+  return tid;
+}
+
+Pmipv6Agent::Pmipv6Agent ()
+  : m_node (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Pmipv6Agent::~Pmipv6Agent ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Pmipv6Agent::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_node = 0;
+  m_profile = 0;
+  Object::DoDispose ();
+}
+
+void Pmipv6Agent::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (this << node);
+  m_node = node;
+}
+
+Ptr<Node> Pmipv6Agent::GetNode (void)
+{
+  NS_LOG_FUNCTION_NOARGS();
+  return m_node;
+}
+
+Ptr<Pmipv6Profile> Pmipv6Agent::GetProfile() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_profile;
+}
+
+void Pmipv6Agent::SetProfile(Ptr<Pmipv6Profile> pf)
+{
+  NS_LOG_FUNCTION (this << pf);
+  
+  m_profile = pf;
+}
+
+uint8_t Pmipv6Agent::Receive (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION ( this << packet << src << dst << interface );
+  
+  Ptr<Packet> p = packet->Copy ();
+  
+  Ipv6MobilityHeader mh;
+  
+  p->PeekHeader (mh);
+  
+  uint8_t mhType = mh.GetMhType ();
+  
+  if (mhType == Ipv6MobilityHeader::IPV6_MOBILITY_BINDING_UPDATE)
+    {
+	  HandlePbu (packet, src, dst, interface);
+	}
+  else if (mhType == Ipv6MobilityHeader::IPV6_MOBILITY_BINDING_ACKNOWLEDGEMENT)
+    {
+	  HandlePba (packet, src, dst, interface);
+	}
+  else
+    {
+	  NS_LOG_ERROR ("Unknown MHType (" << (uint32_t)mhType << ")");
+	}
+	
+  return 0;
+}
+
+void Pmipv6Agent::SendMessage (Ptr<Packet> packet, Ipv6Address dst, uint32_t ttl)
+{
+  NS_LOG_FUNCTION (this << packet << dst << (uint32_t)ttl);
+  
+  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+  
+  NS_ASSERT (ipv6 != 0 && ipv6->GetRoutingProtocol () != 0);
+  
+  Ipv6Header header;
+  SocketIpTtlTag tag;
+  Socket::SocketErrno err;
+  Ptr<Ipv6Route> route;
+  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
+
+  header.SetDestinationAddress (dst);
+  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, err);
+
+  if (route != 0)
+    {
+      tag.SetTtl (ttl);
+      packet->AddPacketTag (tag);
+      Ipv6Address src = route->GetSource ();
+
+      ipv6->Send (packet, src, dst, 135, route);
+    }
+  else
+    {
+      NS_LOG_LOGIC ("no route.. drop pmipv6 message");
+    }
+}
+
+uint8_t Pmipv6Agent::HandlePbu (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION ( this << src << dst );
+  
+  NS_LOG_WARN ("No handler for PBU message");
+
+  return 0;
+}
+
+uint8_t Pmipv6Agent::HandlePba (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION ( this << src << dst );
+  
+  NS_LOG_WARN ("No handler for PBA message");
+  
+  return 0;
+}
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.h ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-agent.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,102 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef PMIPV6_AGENT_H
+#define PMIPV6_AGENT_H
+
+#include "ns3/object.h"
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+class Node;
+class Packet;
+class Ipv6Interface;
+class Pmipv6Profile;
+
+/**
+ * \class Pmip6Agent
+ * \brief An implementation of the PMIPv6 protocol.
+ */
+class Pmipv6Agent : public Object
+{
+public:
+  /**
+   * \brief Interface ID
+   */
+  static TypeId GetTypeId ();
+
+  /**
+   * \brief Constructor.
+   */
+  Pmipv6Agent ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~Pmipv6Agent ();
+
+  /**
+   * \brief Set the node.
+   * \param node the node to set
+   */
+  void SetNode (Ptr<Node> node);
+  
+  /**
+   * \brief Get the node.
+   * \return node
+   */
+  Ptr<Node> GetNode (void);
+  
+  Ptr<Pmipv6Profile> GetProfile() const;
+  void SetProfile (Ptr<Pmipv6Profile> pf);
+  
+  virtual uint8_t Receive (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface);
+  
+  void SendMessage(Ptr<Packet> packet, Ipv6Address dst, uint32_t ttl);
+  
+protected:
+  virtual uint8_t HandlePbu (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface);
+  virtual uint8_t HandlePba (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface);
+  
+  /**
+   * \brief Dispose this object.
+   */
+  virtual void DoDispose ();
+  
+private:
+
+  /**
+   * \brief The node.
+   */
+  Ptr<Node> m_node;
+  
+  Ptr<Pmipv6Profile> m_profile;
+};
+
+} /* namespace ns3 */
+
+#endif /* PMIPV6_AGENT_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,655 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+ 
+#include <stdio.h>
+#include <sstream>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/boolean.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/ipv6-interface.h"
+
+#include "ns3/wifi-net-device.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/regular-wifi-mac.h"
+#include "ns3/wimax-net-device.h"
+
+#include "ns3/ipv6-static-routing-helper.h"
+#include "ns3/ipv6-static-routing.h"
+
+#include "ns3/ipv6-static-source-routing-helper.h"
+
+#include "ipv6-static-source-routing.h"
+#include "ipv6-mobility-header.h"
+#include "ipv6-mobility-demux.h"
+#include "ipv6-mobility-option-header.h"
+#include "ipv6-mobility-option.h"
+#include "ipv6-mobility-l4-protocol.h"
+#include "ipv6-tunnel-l4-protocol.h"
+#include "pmipv6-profile.h"
+#include "pmipv6-prefix-pool.h"
+
+#include "pmipv6-lma.h"
+
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("Pmipv6Lma");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Pmipv6Lma);
+
+Pmipv6Lma::Pmipv6Lma ()
+ : m_bCache (0),
+   m_prefixPool (0)
+{
+}
+
+Pmipv6Lma::~Pmipv6Lma ()
+{
+  m_bCache = 0;
+  m_prefixPool = 0;
+}
+
+Ptr<Pmipv6PrefixPool> Pmipv6Lma::GetPrefixPool () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_prefixPool;
+}
+
+void Pmipv6Lma::SetPrefixPool (Ptr<Pmipv6PrefixPool> pool)
+{
+  NS_LOG_FUNCTION (this << pool);
+  
+  m_prefixPool = pool;
+}
+
+void Pmipv6Lma::NotifyNewAggregate ()
+{
+  if(GetNode () == 0)
+    {
+      Ptr<Node> node = this->GetObject<Node> ();
+	  
+	  m_bCache = CreateObject<BindingCache> ();
+      
+      SetNode (node);
+      m_bCache->SetNode (node);
+    }
+    
+  Pmipv6Agent::NotifyNewAggregate ();
+}
+
+Ptr<Packet> Pmipv6Lma::BuildPba (BindingCache::Entry *bce, uint8_t status)
+{
+  NS_LOG_FUNCTION (this << bce << status);
+  
+   Ptr<Packet> p = Create<Packet> ();
+  
+  Ipv6MobilityBindingAckHeader pba;
+  
+  Ipv6MobilityOptionMobileNodeIdentifierHeader nai;
+  Ipv6MobilityOptionHomeNetworkPrefixHeader hnph;
+  Ipv6MobilityOptionHandoffIndicatorHeader hih;
+  Ipv6MobilityOptionAccessTechnologyTypeHeader atth;
+  Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader mnllidh;
+  Ipv6MobilityOptionTimestampHeader timestamph;
+
+  pba.SetStatus (status);
+  pba.SetFlagP (true);
+  pba.SetSequence (bce->GetLastBindingUpdateSequence ());
+  pba.SetLifetime ((uint16_t)bce->GetReachableTime ().GetSeconds ());
+  
+  nai.SetSubtype (1);
+  nai.SetNodeIdentifier (bce->GetMnIdentifier ());
+  pba.AddOption (nai);
+  
+  std::list<Ipv6Address> hnpList = bce->GetHomeNetworkPrefixes ();
+  for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end(); i++)
+    {
+      hnph.SetPrefix ((*i));
+      hnph.SetPrefixLength (64);
+      pba.AddOption (hnph);
+    }
+  
+  hih.SetHandoffIndicator (bce->GetHandoffIndicator ());
+  pba.AddOption (hih);
+  
+  atth.SetAccessTechnologyType (bce->GetAccessTechnologyType ());
+  pba.AddOption (atth);
+  
+  mnllidh.SetLinkLayerIdentifier (bce->GetMnLinkIdentifier ());
+  pba.AddOption (mnllidh);
+  
+  if (!bce->GetMagLinkAddress ().IsAny ())
+    {
+      Ipv6MobilityOptionLinkLocalAddressHeader llah;
+      
+      llah.SetLinkLocalAddress (bce->GetMagLinkAddress ());
+      pba.AddOption (llah);
+    }
+  
+  timestamph.SetTimestamp (bce->GetLastBindingUpdateTime ());
+  pba.AddOption (timestamph);
+  
+  p->AddHeader (pba);
+  
+  return p;
+}
+
+Ptr<Packet> Pmipv6Lma::BuildPba(Ipv6MobilityBindingUpdateHeader pbu, Ipv6MobilityOptionBundle bundle, uint8_t status)
+{
+  NS_LOG_FUNCTION (this << status);
+  
+   Ptr<Packet> p = Create<Packet> ();
+  
+  Ipv6MobilityBindingAckHeader pba;
+  
+  Ipv6MobilityOptionMobileNodeIdentifierHeader nai;
+  Ipv6MobilityOptionHomeNetworkPrefixHeader hnph;
+  Ipv6MobilityOptionHandoffIndicatorHeader hih;
+  Ipv6MobilityOptionAccessTechnologyTypeHeader atth;
+  Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader mnllidh;
+  Ipv6MobilityOptionTimestampHeader timestamph;
+
+  pba.SetSequence (pbu.GetSequence ());
+  pba.SetFlagP (true);
+  pba.SetStatus (status);
+  
+  nai.SetSubtype (1);
+  nai.SetNodeIdentifier (bundle.GetMnIdentifier ());
+  pba.AddOption (nai);
+  
+  std::list<Ipv6Address> hnpList = bundle.GetHomeNetworkPrefixes ();
+  for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end (); i++)
+    {
+      hnph.SetPrefix ((*i));
+      hnph.SetPrefixLength (64);
+      pba.AddOption (hnph);
+    }
+  
+  hih.SetHandoffIndicator (bundle.GetHandoffIndicator ());
+  pba.AddOption (hih);
+  
+  atth.SetAccessTechnologyType (bundle.GetAccessTechnologyType ());
+  pba.AddOption (atth);
+  
+  mnllidh.SetLinkLayerIdentifier (bundle.GetMnLinkIdentifier ());
+  pba.AddOption (mnllidh);
+  
+  if (!bundle.GetMagLinkAddress ().IsAny ())
+    {
+      Ipv6MobilityOptionLinkLocalAddressHeader llah;
+      
+      llah.SetLinkLocalAddress (bundle.GetMagLinkAddress ());
+      pba.AddOption (llah);
+    }
+  
+  timestamph.SetTimestamp (bundle.GetTimestamp ());
+  pba.AddOption (timestamph);
+  
+  p->AddHeader (pba);
+  
+  return p;
+}
+
+uint8_t Pmipv6Lma::HandlePbu(Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << src << dst << interface);
+  
+  Ptr<Packet> p = packet->Copy ();
+  
+  Ipv6MobilityBindingUpdateHeader pbu;
+  Ipv6MobilityOptionBundle bundle;
+  
+  p->RemoveHeader (pbu);
+  
+  Ptr<Ipv6MobilityDemux> ipv6MobilityDemux = GetNode ()->GetObject<Ipv6MobilityDemux> ();
+  NS_ASSERT (ipv6MobilityDemux);
+  
+  Ptr<Ipv6Mobility> ipv6Mobility = ipv6MobilityDemux->GetMobility (pbu.GetMhType ());
+  NS_ASSERT (ipv6Mobility);
+  
+  uint8_t length = ((pbu.GetHeaderLen () + 1) << 3) - pbu.GetOptionsOffset ();
+  
+  ipv6Mobility->ProcessOptions (packet, pbu.GetOptionsOffset (), length, bundle);
+  
+  uint8_t errStatus = 0;
+  BindingCache::Entry *bce = 0;
+  Pmipv6Profile::Entry *pf = 0;
+  
+  bool delayedRegister = false;
+  
+  /* RFC5213 5.3.1 - 4 Check MN Identifier*/
+  if (bundle.GetMnIdentifier ().IsEmpty ())
+    {
+      errStatus = Ipv6MobilityHeader::BA_STATUS_MISSING_MN_IDENTIFIER_OPTION;
+    }
+  /* 5.3.1 - 7 Check requested MN belongs to this LMA */
+  else if ((pf = GetProfile ()->Lookup (bundle.GetMnIdentifier ())) == 0)
+    {
+      errStatus = Ipv6MobilityHeader::BA_STATUS_NOT_LMA_FOR_THIS_MOBILE_NODE;
+    }
+  /* 5.3.1 - 9 Check Timestamp and sequence */
+  else if (bundle.GetTimestamp ().GetMicroSeconds ()!=0 && bundle.GetTimestamp ()>Simulator::Now ())
+    {
+      errStatus = Ipv6MobilityHeader::BA_STATUS_TIMESTAMP_MISMATCH;
+    }  
+  /* 5.3.1 - 10 Check whether Home Network Prefix(es) exist(s) */    
+  else if (bundle.GetHomeNetworkPrefixes ().size () == 0)
+    {
+      errStatus = Ipv6MobilityHeader::BA_STATUS_MISSING_HOME_NETWORK_PREFIX_OPTION;
+    }
+  /* 5.3.1 - 11 Check Handoff Indicator presents */
+  else if (bundle.GetHandoffIndicator () == Ipv6MobilityHeader::OPT_HI_RESERVED)
+    {
+      errStatus = Ipv6MobilityHeader::BA_STATUS_MISSING_HANDOFF_INDICATOR_OPTION;
+    }
+  /* 5.3.1 - 12 Check Access Technology Type presents */
+  else if (bundle.GetAccessTechnologyType () == Ipv6MobilityHeader::OPT_ATT_RESERVED)
+    {
+      errStatus = Ipv6MobilityHeader::BA_STATUS_MISSING_ACCESS_TECH_TYPE_OPTION;
+    }
+  /* 5.3.1 - 13 Binding Cache entry existence test */
+  else
+    {
+      Identifier mnId = bundle.GetMnIdentifier ();
+      Identifier mnLinkId = bundle.GetMnLinkIdentifier ();
+      std::list<Ipv6Address> hnpList;
+      
+      //copy home network prefixes which has NON_ZERO prefix
+      if(bundle.GetHomeNetworkPrefixes ().size () > 0)
+        {
+          std::list<Ipv6Address> hnpTemp = bundle.GetHomeNetworkPrefixes ();
+         
+          for (std::list<Ipv6Address>::iterator i = hnpTemp.begin (); i != hnpTemp.end (); i++)
+            {
+              if (!(*i).IsAny ())
+                {
+                  hnpList.push_back((*i));
+                }
+            }
+        }
+      
+      if (hnpList.size () > 0)
+        {
+          bool allMatched = false;
+          /* 5.4.1.1 any NON_ZERO Home Network Prefix presents */
+          bce = m_bCache->Lookup (mnId, hnpList, allMatched);
+          
+          /* 5.4.1.1 - 2 Creating a new Mobility session */
+          if (bce == 0)
+            {
+              
+            }
+          else
+            {
+              /* 5.4.1.1 - 4 not all prefix set matched */
+              if (!allMatched)
+                {
+                  bce = 0;
+                  errStatus = Ipv6MobilityHeader::BA_STATUS_BCE_PBU_PREFIX_SET_DO_NOT_MATCH;
+                }
+              else
+                {
+                  NS_LOG_LOGIC ("BCE with all-matched Home Network Prefixes found.");
+                  /* 5.4.1.1 - 5 Updating BCE */
+                }
+            }
+        }
+      else if (!mnLinkId.IsEmpty ())
+        {
+          //5.4.1.2
+          bce = m_bCache->Lookup (mnId, bundle.GetAccessTechnologyType (), mnLinkId);
+          
+          //5.4.1.2 - 3, 4
+          if (bce == 0)
+            {
+              //5.4.1.2 - 3
+              if (bundle.GetHandoffIndicator () == Ipv6MobilityHeader::OPT_HI_HANDOFF_BETWEEN_DIFFERENT_INTERFACES)
+                {
+                  bce = m_bCache->Lookup (mnId);
+                }
+              //5.4.1.2 - 4
+              else if (bundle.GetHandoffIndicator () == Ipv6MobilityHeader::OPT_HI_HANDOFF_STATE_UNKNOWN)
+                {
+                  bce = m_bCache->Lookup (mnId);
+                  delayedRegister = true;
+                }
+            }
+        }
+      else
+        {
+          //5.4.1.3
+          bce = m_bCache->Lookup (mnId);
+          delayedRegister = true;
+        }
+        
+      if (bce != 0)
+        {
+          if (pbu.GetLifetime () > 0)
+            {
+              if ((bce->GetProxyCoa () == src) || bce->IsDeregistering ())
+                {
+                  //update BCE
+                  bce->SetProxyCoa (src);
+                  
+                  bce->SetMnLinkIdentifier (mnLinkId);
+                  bce->SetAccessTechnologyType (bundle.GetAccessTechnologyType ());
+                  bce->SetHandoffIndicator (bundle.GetHandoffIndicator ());
+                  bce->SetMagLinkAddress (bundle.GetMagLinkAddress ());
+                  
+                  bce->SetLastBindingUpdateTime (bundle.GetTimestamp ());
+                  bce->SetReachableTime (Seconds (pbu.GetLifetime ()));
+                  bce->SetLastBindingUpdateSequence (pbu.GetSequence ());
+                  
+                  bce->MarkReachable ();
+                  
+                  //start lifetime timer
+                  bce->StopReachableTimer ();
+                  bce->StartReachableTimer ();
+                }
+              else if (bce->GetProxyCoa () != src)
+                {
+                  NS_LOG_LOGIC ("PBU from another MAG..");
+                  if (bundle.GetHandoffIndicator () == Ipv6MobilityHeader::OPT_HI_HANDOFF_STATE_UNKNOWN && delayedRegister==true)
+                    {
+                      NS_LOG_LOGIC ("Cannot determine handoff-state, performing delayed-registration");
+                          
+                      if (!bce->IsRegistering ())
+                        {
+                          BindingCache::Entry *bce_temp = bce->Copy ();
+                          
+                          bce_temp->SetProxyCoa (src);
+                          
+                          bce_temp->SetMnLinkIdentifier (mnLinkId);
+                          bce_temp->SetAccessTechnologyType (bundle.GetAccessTechnologyType ());
+                          bce_temp->SetHandoffIndicator (bundle.GetHandoffIndicator ());
+                          bce_temp->SetMagLinkAddress (bundle.GetMagLinkAddress ());
+                          
+                          bce_temp->SetLastBindingUpdateTime (bundle.GetTimestamp ());
+                          bce_temp->SetReachableTime (Seconds (pbu.GetLifetime ()));
+                          bce_temp->SetLastBindingUpdateSequence (pbu.GetSequence ());
+                          
+                          bce_temp->SetHomeNetworkPrefixes (bundle.GetHomeNetworkPrefixes ());
+                          
+                          bce->SetTentativeEntry (bce_temp);
+                          
+                          bce->MarkRegistering ();
+                      
+                          bce->StopRegisterTimer ();
+                          bce->StartRegisterTimer ();
+                        }
+                      else
+                        {
+                          NS_LOG_LOGIC ("Already in delayed registration.. Skipped");
+                        }
+                      
+                      return 0;
+                    }
+                  else
+                    {
+                      NS_LOG_LOGIC ("Handoff in two different mags for the same interface");
+                      
+                      //update BCE
+                      bce->SetProxyCoa (src);
+                      
+                      bce->SetMnLinkIdentifier (mnLinkId);
+                      bce->SetAccessTechnologyType (bundle.GetAccessTechnologyType ());
+                      bce->SetHandoffIndicator (bundle.GetHandoffIndicator ());
+                      bce->SetMagLinkAddress (bundle.GetMagLinkAddress ());
+                      
+                      bce->SetLastBindingUpdateTime (bundle.GetTimestamp ());
+                      bce->SetReachableTime (Seconds (pbu.GetLifetime ()));
+                      bce->SetLastBindingUpdateSequence (pbu.GetSequence ());
+                      
+                        ModifyTunnelAndRouting (bce);
+
+                      bce->MarkReachable ();
+                      
+                      //start lifetime timer
+                      bce->StopReachableTimer ();
+                      bce->StartReachableTimer ();                      
+                    }
+                }
+            }
+          else
+            {
+              NS_LOG_LOGIC ("Lifetime is zero.. Deregistering..");
+              if (bce->GetProxyCoa () == src)
+                {
+                  //Deregistering
+                  bce->MarkDeregistering ();
+                  
+                  bce->StartDeregisterTimer ();
+                }
+            }
+        }
+      else
+        {
+          if (pbu.GetLifetime () > 0)
+            {
+              //No Binding Cache Exists
+              NS_LOG_LOGIC ("Createing new Binding Cache Entry");
+              
+              bce = m_bCache->Add (mnId);
+
+              bce->SetProxyCoa (src);
+              
+              bce->SetMnLinkIdentifier (mnLinkId);
+              bce->SetAccessTechnologyType (bundle.GetAccessTechnologyType ());
+              bce->SetHandoffIndicator (bundle.GetHandoffIndicator ());
+              bce->SetMagLinkAddress (bundle.GetMagLinkAddress ());
+              
+              bce->SetLastBindingUpdateTime (bundle.GetTimestamp ());
+              bce->SetReachableTime (Seconds (pbu.GetLifetime ()));
+              bce->SetLastBindingUpdateSequence (pbu.GetSequence ());
+              
+              //allocate new prefix
+              std::list<Ipv6Address> hnpList;
+              
+              if (pf && pf->GetHomeNetworkPrefixes ().size () > 0)
+                {
+                  bce->SetHomeNetworkPrefixes (pf->GetHomeNetworkPrefixes ());
+                }
+              else
+                {
+                  Ipv6Address prefix = m_prefixPool->Assign ();
+                  
+                  NS_LOG_LOGIC ("Assign new Prefix from Pool: " << prefix);
+                  
+                  hnpList.push_back (prefix);
+                  
+                  bce->SetHomeNetworkPrefixes (hnpList);
+                  
+                  if (pf)
+                    {
+                      pf->SetHomeNetworkPrefixes (hnpList);
+                    }
+                }
+                
+              //create tunnel
+              SetupTunnelAndRouting (bce);
+              
+              bce->MarkReachable ();
+              
+              //start lifetime timer
+              bce->StartReachableTimer ();
+            }
+        }
+    
+      //routing setup && tunneling
+    
+      errStatus = Ipv6MobilityHeader::BA_STATUS_BINDING_UPDATE_ACCEPTED;
+      
+    }
+    
+    //send PBA
+    Ptr<Packet> pktPba;
+    if (bce != 0)
+      {
+        pktPba = BuildPba (bce, errStatus);
+      }
+    else
+      {
+        pktPba = BuildPba (pbu, bundle, errStatus);
+      }
+      
+    SendMessage (pktPba, src, 64);
+
+  return 0;
+}
+
+bool Pmipv6Lma::SetupTunnelAndRouting (BindingCache::Entry *bce)
+{
+  NS_LOG_FUNCTION (this << bce);
+  
+  //create tunnel
+  Ptr<Ipv6TunnelL4Protocol> th = GetNode ()->GetObject<Ipv6TunnelL4Protocol> ();
+  NS_ASSERT (th);
+  
+  uint16_t tunnelIf = th->AddTunnel (bce->GetProxyCoa ());
+  
+  bce->SetTunnelIfIndex (tunnelIf);
+  
+  //routing setup by static routing protocol
+  Ipv6StaticRoutingHelper staticRoutingHelper;
+  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+  
+  std::list<Ipv6Address> hnpList = bce->GetHomeNetworkPrefixes ();
+  
+  Ptr<Ipv6StaticRouting> staticRouting = staticRoutingHelper.GetStaticRouting (ipv6);
+  
+  for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end (); i++)
+    {
+      NS_LOG_LOGIC ("Add Route " << (*i) << "/64 via " << (uint32_t)bce->GetTunnelIfIndex ());
+      staticRouting->AddNetworkRouteTo ((*i), Ipv6Prefix (64), bce->GetTunnelIfIndex ());
+    }
+    
+  return true;
+}
+
+void Pmipv6Lma::ClearTunnelAndRouting (BindingCache::Entry *bce)
+{
+  NS_LOG_FUNCTION (this << bce);
+  
+  //routing setup by static routing protocol
+  Ipv6StaticRoutingHelper staticRoutingHelper;
+  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+  
+  std::list<Ipv6Address> hnpList = bce->GetHomeNetworkPrefixes ();
+  
+  Ptr<Ipv6StaticRouting> staticRouting = staticRoutingHelper.GetStaticRouting (ipv6);
+  
+  for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end (); i++)
+    {
+      NS_LOG_LOGIC ("Add Route " << (*i) << "/64 via " << (uint32_t)bce->GetTunnelIfIndex ());
+      staticRouting->RemoveRoute ((*i), Ipv6Prefix (64), bce->GetTunnelIfIndex (), (*i));
+    }
+    
+  //create tunnel
+  Ptr<Ipv6TunnelL4Protocol> th = GetNode ()->GetObject<Ipv6TunnelL4Protocol> ();
+  NS_ASSERT (th);
+  
+  th->RemoveTunnel (bce->GetProxyCoa ());
+  
+  bce->SetTunnelIfIndex (-1);
+}
+
+bool Pmipv6Lma::ModifyTunnelAndRouting (BindingCache::Entry *bce)
+{
+  NS_LOG_FUNCTION (this << bce);
+  uint16_t oldTunnelIf = -1;
+  
+  Ptr<Ipv6TunnelL4Protocol> th = GetNode ()->GetObject<Ipv6TunnelL4Protocol> ();
+  NS_ASSERT (th);
+  Ipv6StaticRoutingHelper staticRoutingHelper;
+  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+  Ptr<Ipv6StaticRouting> staticRouting = staticRoutingHelper.GetStaticRouting (ipv6);
+  
+  oldTunnelIf = bce->GetTunnelIfIndex ();
+  uint16_t tunnelIf = th->ModifyTunnel (bce->GetOldProxyCoa (), bce->GetProxyCoa ());
+  
+  if (oldTunnelIf != tunnelIf)
+    {
+      std::list<Ipv6Address> hnpList = bce->GetHomeNetworkPrefixes ();
+      
+      bce->SetTunnelIfIndex (tunnelIf);
+      for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end (); i++)
+        {
+          NS_LOG_LOGIC ("Modify Route " << (*i) << "/64 via " << (uint32_t)oldTunnelIf << " to " << tunnelIf);
+          staticRouting->RemoveRoute ((*i), Ipv6Prefix (64), oldTunnelIf, (*i));
+          staticRouting->AddNetworkRouteTo ((*i), Ipv6Prefix (64), tunnelIf);
+        }
+    }
+    
+  return true;
+}
+
+void Pmipv6Lma::DoDelayedRegistration (BindingCache::Entry *bce)
+{
+  NS_LOG_FUNCTION (this << bce);
+  
+  BindingCache::Entry *bce_temp = bce->GetTentativeEntry ();
+  NS_ASSERT (bce_temp);
+  bce->SetTentativeEntry (0);
+  
+  NS_LOG_LOGIC ("late registration " << bce << " with temp BCE " << bce_temp);
+  
+  bce->SetProxyCoa (bce_temp->GetProxyCoa ());
+  
+  bce->SetAccessTechnologyType (bce_temp->GetAccessTechnologyType ());
+  bce->SetHandoffIndicator (bce_temp->GetHandoffIndicator ());
+  bce->SetMagLinkAddress (bce_temp->GetMagLinkAddress ());
+  
+  bce->SetLastBindingUpdateTime (bce_temp->GetLastBindingUpdateTime ());
+  bce->SetReachableTime (bce_temp->GetReachableTime ());
+  bce->SetLastBindingUpdateSequence (bce_temp->GetLastBindingUpdateSequence ());  
+
+  delete bce_temp;
+  
+  ModifyTunnelAndRouting (bce);
+
+  bce->MarkReachable ();
+
+  //start lifetime timer
+  bce->StopReachableTimer ();
+  bce->StartReachableTimer ();
+    
+  //send PBA
+  Ptr<Packet> pktPba;
+  pktPba = BuildPba (bce, Ipv6MobilityHeader::BA_STATUS_BINDING_UPDATE_ACCEPTED);
+  
+  SendMessage (pktPba, bce->GetProxyCoa (), 64);
+}
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.h ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-lma.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,69 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef PMIPV6_LMA_H
+#define PMIPV6_LMA_H
+
+#include "pmipv6-agent.h"
+#include "binding-cache.h"
+
+namespace ns3
+{
+class Packet;
+class Ipv6MobilityOptionBundle;
+class Pmipv6PrefixPool;
+
+class Pmipv6Lma : public Pmipv6Agent {
+public:
+  Pmipv6Lma ();
+  
+  virtual ~Pmipv6Lma ();
+  
+  Ptr<Pmipv6PrefixPool> GetPrefixPool () const;
+  void SetPrefixPool (Ptr<Pmipv6PrefixPool> pool);
+  
+  void DoDelayedRegistration (BindingCache::Entry *bce);
+  
+protected:
+  virtual void NotifyNewAggregate ();
+  
+  Ptr<Packet> BuildPba (BindingCache::Entry *bce, uint8_t status);
+  Ptr<Packet> BuildPba (Ipv6MobilityBindingUpdateHeader pbu, Ipv6MobilityOptionBundle bundle, uint8_t status);
+  
+  virtual uint8_t HandlePbu (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface);
+  
+  bool SetupTunnelAndRouting (BindingCache::Entry *bce);
+  bool ModifyTunnelAndRouting (BindingCache::Entry *bce);
+  void ClearTunnelAndRouting (BindingCache::Entry *bce); 
+
+private:
+  Ptr<BindingCache> m_bCache;
+  
+  Ptr<Pmipv6PrefixPool> m_prefixPool;
+};
+
+} /* namespace ns3 */
+
+#endif /* PMIPV6_LMA_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,611 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include <stdio.h>
+#include <sstream>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/ipv6-interface.h"
+
+#include "ns3/wifi-net-device.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/regular-wifi-mac.h"
+#include "ns3/wimax-net-device.h"
+
+#include "ns3/point-to-point-net-device.h"
+
+#include "ns3/ipv6-static-routing-helper.h"
+#include "ns3/ipv6-static-routing.h"
+
+#include "ns3/ipv6-static-source-routing-helper.h"
+
+#include "ipv6-static-source-routing.h"
+#include "ipv6-mobility-header.h"
+#include "ipv6-mobility-demux.h"
+#include "ipv6-mobility-option-header.h"
+#include "ipv6-mobility-option.h"
+#include "ipv6-mobility-l4-protocol.h"
+#include "ipv6-tunnel-l4-protocol.h"
+#include "unicast-radvd.h"
+#include "pmipv6-profile.h"
+#include "pmipv6-mag-notifier.h"
+#include "pmipv6-mag.h"
+
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("Pmipv6Mag");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Pmipv6Mag);
+
+Pmipv6Mag::Pmipv6Mag ()
+: m_useRemoteAp (false),
+  m_sequence (0),
+  m_buList (0),
+  m_radvd (0)
+{
+}
+
+Pmipv6Mag::~Pmipv6Mag ()
+{
+}
+
+void Pmipv6Mag::NotifyNewAggregate ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (GetNode () == 0)
+    {
+      Ptr<Node> node = this->GetObject<Node> ();
+
+      SetNode (node);
+
+	  m_buList = CreateObject<BindingUpdateList> ();
+      m_buList->SetNode (node);
+
+      if (!m_useRemoteAp)
+        {
+          //register linkup callback.
+          uint32_t nDev = node->GetNDevices ();
+
+          for (uint32_t i = 0; i < nDev; ++i)
+            {
+              Ptr<NetDevice> dev = node->GetDevice (i);
+              Ptr<WifiNetDevice> wDev = dev->GetObject<WifiNetDevice> ();
+
+              if (wDev)
+                {
+                  Ptr<WifiMac> mac = wDev->GetMac ();
+                  Ptr<RegularWifiMac> rmac = mac->GetObject<RegularWifiMac> ();
+
+                  if (!mac || !rmac)
+                    {
+                      continue;
+                    }
+
+                  rmac->SetNewHostCallback (MakeCallback (&Pmipv6Mag::HandleNewNode, this));
+                }
+            }
+        }
+	  else
+	    {
+		  Ptr<Pmipv6MagNotifier> noti = GetNode ()->GetObject<Pmipv6MagNotifier> ();
+		  
+		  NS_ASSERT (noti != 0);
+		  
+		  noti->SetNewNodeCallback (MakeCallback (&Pmipv6Mag::HandleNewNode, this));
+		}
+
+      //RADVD Setting
+      m_radvd = CreateObject<UnicastRadvd> ();
+      node->AddApplication (m_radvd);
+
+      m_radvd->SetStartTime (Seconds (1.));
+    }
+
+  Pmipv6Agent::NotifyNewAggregate ();
+}
+
+bool Pmipv6Mag::IsUseRemoteAP () const
+{
+  return m_useRemoteAp;
+}
+
+void Pmipv6Mag::UseRemoteAP (bool remoteAp)
+{
+  m_useRemoteAp = remoteAp;
+}
+
+Ipv6Address Pmipv6Mag::GetLinkLocalAddress (Ipv6Address addr)
+{
+  NS_LOG_FUNCTION (this << addr);
+
+  Ipv6Address lla;
+
+  Ptr<Ipv6L3Protocol> ipv6 = GetNode ()->GetObject<Ipv6L3Protocol> ();
+
+  NS_ASSERT (ipv6 != 0 && ipv6->GetRoutingProtocol () != 0);
+
+  Ptr<Packet> p = Create<Packet> ();
+
+  Ipv6Header header;
+  SocketIpTtlTag tag;
+  Socket::SocketErrno err;
+  Ptr<Ipv6Route> route;
+  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
+
+  header.SetDestinationAddress (addr);
+  route = ipv6->GetRoutingProtocol ()->RouteOutput (p, header, oif, err);
+
+  if (route != 0)
+    {
+      Ptr<NetDevice> device = route->GetOutputDevice ();
+      Ptr<Ipv6Interface> iif = ipv6->GetInterface(ipv6->GetInterfaceForDevice (device));
+      Ipv6InterfaceAddress iia = iif->GetLinkLocalAddress ();
+
+      lla = iia.GetAddress ();
+
+      NS_LOG_LOGIC ( "MAG's outgoing interface LLA is " << lla);
+    }
+
+  return lla;
+}
+
+uint16_t Pmipv6Mag::GetSequence ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return ++m_sequence;
+}
+
+Ptr<UnicastRadvd> Pmipv6Mag::GetRadvd () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  return m_radvd;
+}
+
+Ptr<Packet> Pmipv6Mag::BuildPbu (BindingUpdateList::Entry *bule)
+{
+  NS_LOG_FUNCTION(this << bule);
+
+  Ptr<Packet> p = Create<Packet> ();
+
+  Ipv6MobilityBindingUpdateHeader pbu;
+
+  Ipv6MobilityOptionMobileNodeIdentifierHeader mnidh;
+  Ipv6MobilityOptionHomeNetworkPrefixHeader hnph;
+  Ipv6MobilityOptionHandoffIndicatorHeader hih;
+  Ipv6MobilityOptionAccessTechnologyTypeHeader atth;
+  Ipv6MobilityOptionMobileNodeLinkLayerIdentifierHeader mnllidh;
+  Ipv6MobilityOptionTimestampHeader timestamph;
+
+  pbu.SetSequence (bule->GetLastBindingUpdateSequence ());
+  pbu.SetFlagA (true);
+  pbu.SetFlagH (true);
+  pbu.SetFlagL (true);
+  pbu.SetFlagP (true);
+
+  pbu.SetLifetime ((uint16_t)Ipv6MobilityL4Protocol::MAX_BINDING_LIFETIME);
+
+  //Add Mobile Node Identifier Option
+  mnidh.SetSubtype (1);
+  mnidh.SetNodeIdentifier (bule->GetMnIdentifier ());
+
+  pbu.AddOption (mnidh);
+
+  //Add Home Network Prerfix List (if it has)
+  if (bule->GetHomeNetworkPrefixes ().size () > 0)
+    {
+      std::list<Ipv6Address> hnp = bule->GetHomeNetworkPrefixes ();
+
+      for (std::list<Ipv6Address>::iterator i = hnp.begin(); i != hnp.end(); i++)
+        {
+          hnph.SetPrefix ((*i));
+          hnph.SetPrefixLength (64);
+
+          pbu.AddOption (hnph);
+        }
+    }
+  else
+    {
+      hnph.SetPrefix (Ipv6Address::GetAny ());
+      hnph.SetPrefixLength (0);
+
+      pbu.AddOption (hnph);
+    }
+
+  //Add Handoff Indicator Option
+  hih.SetHandoffIndicator (bule->GetHandoffIndicator ());
+
+  pbu.AddOption (hih);
+
+  //Add Access Technology Type Option
+  atth.SetAccessTechnologyType (bule->GetAccessTechnologyType ());
+
+  pbu.AddOption (atth);
+
+  //Add MobileNode Link Identifier Option
+  mnllidh.SetLinkLayerIdentifier (bule->GetMnLinkIdentifier ());
+
+  pbu.AddOption (mnllidh);
+
+  if (!bule->GetMagLinkAddress ().IsAny ())
+    {
+      Ipv6MobilityOptionLinkLocalAddressHeader llah;
+
+      llah.SetLinkLocalAddress (bule->GetMagLinkAddress ());
+
+      pbu.AddOption (llah);
+    }
+
+  //Add Timestamp Option
+  timestamph.SetTimestamp (bule->GetLastBindingUpdateTime ());
+  pbu.AddOption (timestamph);
+
+  p->AddHeader(pbu);
+
+  return p;
+}
+
+void Pmipv6Mag::HandleNewNode (Mac48Address from, Mac48Address to, uint8_t att)
+{
+  NS_LOG_FUNCTION (this << from << to <<(uint32_t)att);
+  NS_ASSERT ( GetProfile() != 0 );
+
+  //get Profile
+  Pmipv6Profile::Entry *pf = GetProfile ()->Lookup (Identifier (from));
+
+  if (pf == 0)
+    {
+      NS_LOG_LOGIC ("No profile exists for MAC(" << from << ") ATT(" << (uint32_t)att << ")");
+      return;
+    }
+
+  //check BUL
+  BindingUpdateList::Entry *bule = m_buList->Lookup (pf->GetMnIdentifier ());
+
+  if (bule == 0)
+    {
+      bule = m_buList->Add (pf->GetMnIdentifier ());
+    }
+
+  bule->SetAccessTechnologyType (att);
+  bule->SetMnLinkIdentifier (pf->GetMnLinkIdentifier ());
+  bule->SetLmaAddress (pf->GetLmaAddress ());
+
+  if (pf->GetHomeNetworkPrefixes ().size () > 0)
+    {
+      bule->SetHomeNetworkPrefixes (pf->GetHomeNetworkPrefixes ());
+    }
+
+  //XXX: how to determine proper HI(Handoff Indicator) value??
+  bule->SetHandoffIndicator (Ipv6MobilityHeader::OPT_HI_HANDOFF_STATE_UNKNOWN);
+
+  Ipv6Address lla = GetLinkLocalAddress (bule->GetLmaAddress ());
+  if (!lla.IsAny ())
+    {
+      bule->SetMagLinkAddress (lla);
+    }
+
+  //Get IfIndex from "to"
+  uint32_t nDev = GetNode ()->GetNDevices ();
+  Ptr<NetDevice> dev = 0;
+  bool found = false;
+
+  for (uint32_t i = 0; i < nDev; ++i)
+    {
+      dev = GetNode ()->GetDevice (i);
+
+      if (Mac48Address::ConvertFrom (dev->GetAddress ()) == to)
+        {
+          found = true;
+          NS_LOG_LOGIC ("Found Device (" << dev->GetIfIndex () << ") for MAC address (" << to << ")");
+
+          break;
+        }
+    }
+
+  if (found == false)
+    {
+      NS_LOG_WARN ("Device Not Found for MAC address (" << to << ")");
+
+      return;
+    }
+
+  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+  NS_ASSERT (ipv6);
+
+  int32_t ifIndex = ipv6->GetInterfaceForDevice (dev);
+
+  if (ifIndex == -1)
+    {
+      NS_LOG_LOGIC ("No Ipv6Interface for Device " << dev->GetIfIndex ());
+
+      return;
+    }
+
+  bule->SetIfIndex (ifIndex);
+
+  //preset header information
+  bule->SetLastBindingUpdateSequence (GetSequence ());
+  //Cut to micro-seconds
+  bule->SetLastBindingUpdateTime (MicroSeconds (Simulator::Now ().GetMicroSeconds ()));
+
+  Ptr<Packet> p = BuildPbu (bule);
+
+  //save packet
+  bule->SetPbuPacket (p);
+
+  //reset (for the first registration)
+  bule->ResetRetryCount ();
+
+  //send PBU
+  SendMessage (p->Copy (), bule->GetLmaAddress (), 64);
+
+  bule->StartRetransTimer ();
+
+  if (bule->IsReachable ())
+    {
+      bule->MarkRefreshing ();
+    }
+  else
+    {
+      bule->MarkUpdating ();
+    }
+}
+
+uint8_t Pmipv6Mag::HandlePba (Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << src << dst << interface);
+  Ptr<Packet> p = packet->Copy ();
+
+  Ipv6MobilityBindingAckHeader pba;
+  Ipv6MobilityOptionBundle bundle;
+
+  p->RemoveHeader (pba);
+
+  Ptr<Ipv6MobilityDemux> ipv6MobilityDemux = GetNode ()->GetObject<Ipv6MobilityDemux> ();
+  NS_ASSERT (ipv6MobilityDemux);
+
+  Ptr<Ipv6Mobility> ipv6Mobility = ipv6MobilityDemux->GetMobility (pba.GetMhType ());
+  NS_ASSERT (ipv6Mobility);
+
+  uint8_t length = ((pba.GetHeaderLen () + 1) << 3) - pba.GetOptionsOffset ();
+
+  ipv6Mobility->ProcessOptions (packet, pba.GetOptionsOffset (), length, bundle);
+
+  //option check
+  //Error Process for Mandatory Options
+  if (bundle.GetMnIdentifier ().IsEmpty () ||
+      bundle.GetHomeNetworkPrefixes ().size () == 0 ||
+      bundle.GetAccessTechnologyType () == Ipv6MobilityHeader::OPT_ATT_RESERVED ||
+      bundle.GetHandoffIndicator () == Ipv6MobilityHeader::OPT_HI_RESERVED ||
+      bundle.GetTimestamp ().GetMicroSeconds () == 0)
+    {
+      NS_LOG_LOGIC ("PBA Option missing.. Ignored.");
+
+      return 0;
+    }
+
+  if (bundle.GetTimestamp () > Simulator::Now ())
+    {
+      NS_LOG_LOGIC ("Timestamp is mismatched. Ignored.");
+
+      return 0;
+    }
+
+  BindingUpdateList::Entry *bule = m_buList->Lookup (bundle.GetMnIdentifier ());
+
+  if (bule == 0)
+    {
+      NS_LOG_LOGIC ("No matched PBA for PBU. Ignored.");
+
+      return 0;
+    }
+
+  //check for timestamp and sequence
+  if (bule->GetLastBindingUpdateSequence () != pba.GetSequence () ||
+      bule->GetLastBindingUpdateTime () != bundle.GetTimestamp ())
+    {
+      NS_LOG_LOGIC ("Sequence or Timestamp mismatch. Ignored. this: "
+                    << bule->GetLastBindingUpdateTime ()
+                    << ", from: "
+                    << bundle.GetTimestamp ());
+
+      return 0;
+    }
+
+  //check status code
+  switch (pba.GetStatus ())
+    {
+    case Ipv6MobilityHeader::BA_STATUS_BINDING_UPDATE_ACCEPTED:
+    {
+      bule->StopRetransTimer ();
+      bule->SetPbuPacket (0);
+
+      //update information
+      bule->SetHomeNetworkPrefixes (bundle.GetHomeNetworkPrefixes ());
+      bule->SetReachableTime (Seconds (pba.GetLifetime ()));
+
+      if (pba.GetLifetime () > 0)
+        {
+          if (bule->IsUpdating ())
+            {
+              //register radvd interface
+              SetupRadvdInterface (bule);
+
+              //create tunnel & setup routing
+              SetupTunnelAndRouting (bule);
+            }
+
+          bule->MarkReachable ();
+
+          //Setup lifetime
+          bule->StopRefreshTimer ();
+          bule->StartRefreshTimer ();
+          bule->StopReachableTimer ();
+          bule->StartReachableTimer ();
+        }
+      else
+        {
+          //de-registering
+          ClearRadvdInterface (bule);
+          ClearTunnelAndRouting (bule);
+
+          m_buList->Remove (bule);
+        }
+      break;
+    }
+
+    default:
+      NS_LOG_LOGIC ("Error occurred code=" << pba.GetStatus ());
+    }
+
+  return 0;
+}
+
+bool Pmipv6Mag::SetupTunnelAndRouting (BindingUpdateList::Entry *bule)
+{
+  NS_LOG_FUNCTION (this << bule);
+
+  //create tunnel
+  Ptr<Ipv6TunnelL4Protocol> th = GetNode ()->GetObject<Ipv6TunnelL4Protocol> ();
+  NS_ASSERT (th);
+
+  uint16_t tunnelIf = th->AddTunnel (bule->GetLmaAddress ());
+
+  bule->SetTunnelIfIndex (tunnelIf);
+
+  //routing setup by static routing protocol
+  Ipv6StaticRoutingHelper staticRoutingHelper;
+  Ipv6StaticSourceRoutingHelper sourceRoutingHelper;
+
+  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+
+  Ptr<Ipv6StaticRouting> staticRouting = staticRoutingHelper.GetStaticRouting (ipv6);
+  Ptr<Ipv6StaticSourceRouting> sourceRouting = sourceRoutingHelper.GetStaticSourceRouting (ipv6);
+
+  NS_ASSERT (staticRouting && sourceRouting);
+
+  std::list<Ipv6Address> hnpList = bule->GetHomeNetworkPrefixes ();
+
+  for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end (); i++)
+    {
+      NS_LOG_LOGIC ("Add Route to " << (*i) << "/64 via " << (uint32_t)bule->GetIfIndex ());
+      staticRouting->AddNetworkRouteTo ((*i), Ipv6Prefix (64), bule->GetIfIndex ());
+
+      NS_LOG_LOGIC ("Add Source Route from " << (*i) << "/64 via " << (uint32_t)bule->GetTunnelIfIndex ());
+      sourceRouting->AddNetworkRouteFrom ((*i), Ipv6Prefix (64), bule->GetTunnelIfIndex ());
+    }
+
+  return true;
+}
+
+void Pmipv6Mag::ClearTunnelAndRouting (BindingUpdateList::Entry *bule)
+{
+  NS_LOG_FUNCTION (this << bule);
+
+  //routing setup by static routing protocol
+  Ipv6StaticRoutingHelper staticRoutingHelper;
+  Ipv6StaticSourceRoutingHelper sourceRoutingHelper;
+
+  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+
+  Ptr<Ipv6StaticRouting> staticRouting = staticRoutingHelper.GetStaticRouting (ipv6);
+  Ptr<Ipv6StaticSourceRouting> sourceRouting = sourceRoutingHelper.GetStaticSourceRouting (ipv6);
+
+  NS_ASSERT (staticRouting && sourceRouting);
+
+  std::list<Ipv6Address> hnpList = bule->GetHomeNetworkPrefixes ();
+
+  for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end (); i++)
+    {
+      NS_LOG_LOGIC ("Remove Route to " << (*i) << "/64 via " << (uint32_t)bule->GetIfIndex ());
+      staticRouting->RemoveRoute ((*i), Ipv6Prefix (64), bule->GetIfIndex (), (*i));
+
+      NS_LOG_LOGIC ("Remove Source Route from " << (*i) << "/64 via " << (uint32_t)bule->GetTunnelIfIndex ());
+      sourceRouting->RemoveRoute ((*i), Ipv6Prefix (64), bule->GetTunnelIfIndex (), (*i));
+    }
+
+  //remove tunnel
+  Ptr<Ipv6TunnelL4Protocol> th = GetNode ()->GetObject<Ipv6TunnelL4Protocol> ();
+  NS_ASSERT (th);
+
+  th->RemoveTunnel (bule->GetLmaAddress ());
+  bule->SetTunnelIfIndex (-1);
+}
+
+bool Pmipv6Mag::SetupRadvdInterface (BindingUpdateList::Entry *bule)
+{
+  NS_LOG_FUNCTION (this << bule);
+
+  uint32_t ifIndex = bule->GetIfIndex ();
+
+  Ptr<UnicastRadvdInterface> uri = Create<UnicastRadvdInterface> (ifIndex, 5000, 1000);
+  Identifier linkId = bule->GetMnLinkIdentifier ();
+
+  Mac48Address phyId;
+  uint8_t buf[Identifier::MAX_SIZE];
+
+  linkId.CopyTo (buf, Identifier::MAX_SIZE);
+  phyId.CopyFrom (buf);
+
+  uri->SetPhysicalAddress (phyId);
+
+  std::list<Ipv6Address> hnpList = bule->GetHomeNetworkPrefixes ();
+
+  for (std::list<Ipv6Address>::iterator i = hnpList.begin (); i != hnpList.end (); i++)
+    {
+      Ptr<RadvdPrefix> prefix = Create<RadvdPrefix> ((*i), 64, 3, 5);
+      uri->AddPrefix (prefix);
+    }
+
+  GetRadvd ()->AddConfiguration (uri);
+
+  bule->SetRadvdIfIndex (uri->GetInterface ());
+
+  return true;
+}
+
+void Pmipv6Mag::ClearRadvdInterface (BindingUpdateList::Entry *bule)
+{
+  NS_LOG_FUNCTION (this << bule);
+
+  GetRadvd ()->RemoveConfiguration (bule->GetRadvdIfIndex ());
+
+  bule->SetRadvdIfIndex (-1);
+}
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.h ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,79 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef PMIPV6_MAG_H
+#define PMIPV6_MAG_H
+
+#include "pmipv6-agent.h"
+#include "binding-update-list.h"
+
+namespace ns3
+{
+class UnicastRadvd;
+class Mac48Address;
+
+class Pmipv6Mag : public Pmipv6Agent {
+public:
+  Pmipv6Mag();
+  
+  virtual ~Pmipv6Mag();
+  
+  bool IsUseRemoteAP() const;
+  void UseRemoteAP(bool remoteAp);
+  
+  uint16_t GetSequence();
+  
+  bool SetupTunnelAndRouting(BindingUpdateList::Entry *bule);
+  void ClearTunnelAndRouting(BindingUpdateList::Entry *bule); 
+
+  bool SetupRadvdInterface(BindingUpdateList::Entry *bule);
+  void ClearRadvdInterface(BindingUpdateList::Entry *bule);
+  
+  Ptr<Packet> BuildPbu(BindingUpdateList::Entry *bule);
+  
+protected:
+  virtual void NotifyNewAggregate();
+  
+  Ipv6Address GetLinkLocalAddress(Ipv6Address addr);
+  
+  Ptr<UnicastRadvd> GetRadvd() const;
+  
+  virtual void HandleNewNode(Mac48Address from, Mac48Address to, uint8_t att);
+  virtual uint8_t HandlePba(Ptr<Packet> packet, const Ipv6Address &src, const Ipv6Address &dst, Ptr<Ipv6Interface> interface);
+  
+private:
+  
+  bool m_useRemoteAp;
+  
+  uint16_t m_sequence;
+  
+  Ptr<BindingUpdateList> m_buList;
+  
+  Ptr<UnicastRadvd> m_radvd;
+};
+
+} /* namespace ns3 */
+
+#endif /* PMIPV6_MAG_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.cc	2014-02-04 10:10:49.000000000 +0100
@@ -0,0 +1,392 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include <stdio.h>
+#include <sstream>
+
+#include "ns3/log.h"
+#include "ns3/assert.h"
+#include "ns3/packet.h"
+#include "ns3/node.h"
+#include "ns3/boolean.h"
+#include "ns3/ipv6-routing-protocol.h"
+#include "ns3/ipv6-route.h"
+#include "ns3/wifi-net-device.h"
+#include "ns3/wifi-mac.h"
+#include "ns3/regular-wifi-mac.h"
+#include "ns3/wimax-net-device.h"
+#include "ns3/point-to-point-net-device.h"
+
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/ipv6-interface.h"
+
+#include "identifier.h"
+#include "ipv6-mobility-header.h"
+
+#include "ipv6-mobility-option-header.h"
+#include "ipv6-mobility-option.h"
+
+#include "ipv6-mobility-l4-protocol.h"
+
+#include "pmipv6-mag-notifier.h"
+
+using namespace std;
+
+NS_LOG_COMPONENT_DEFINE ("Pmipv6MagNotifier");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED(Pmipv6MagNotifyHeader);
+
+TypeId Pmipv6MagNotifyHeader::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Pmipv6MagNotifyHeader")
+    .SetParent<Header> ()
+    .AddConstructor<Pmipv6MagNotifyHeader> ()
+    ;
+  return tid;
+}
+
+TypeId Pmipv6MagNotifyHeader::GetInstanceTypeId () const
+{
+  return GetTypeId ();
+}
+
+Pmipv6MagNotifyHeader::Pmipv6MagNotifyHeader()
+ : m_nextHeader(59), /* no next header */
+   m_length(1)
+{
+  memset(m_reserved, 0, sizeof(m_reserved));
+}
+
+Pmipv6MagNotifyHeader::~Pmipv6MagNotifyHeader()
+{
+}
+
+Mac48Address Pmipv6MagNotifyHeader::GetMacAddress() const
+{
+  return m_macAddress;
+}
+
+void Pmipv6MagNotifyHeader::SetMacAddress(Mac48Address macaddr)
+{
+  m_macAddress = macaddr;
+}
+
+uint8_t Pmipv6MagNotifyHeader::GetAccessTechnologyType() const
+{
+  return m_accessTechnologyType;
+}
+
+void Pmipv6MagNotifyHeader::SetAccessTechnologyType(uint8_t att)
+{
+  m_accessTechnologyType =  att;
+} 
+
+void Pmipv6MagNotifyHeader::Print (std::ostream& os) const
+{
+  os << "( from: " << m_macAddress << ", ATT: " << (uint32_t)m_accessTechnologyType << ")";
+}
+
+uint32_t Pmipv6MagNotifyHeader::GetSerializedSize () const
+{
+  return 16;
+}
+
+void Pmipv6MagNotifyHeader::Serialize (Buffer::Iterator start) const
+{
+  uint8_t buf[6];
+  Buffer::Iterator i = start;
+  
+  i.WriteU8(m_nextHeader);
+  i.WriteU8(m_length);
+
+  m_macAddress.CopyTo(buf);
+ 
+  i.Write(buf, 6);
+  
+  i.WriteU8(m_accessTechnologyType);
+  
+  i.Write(m_reserved, sizeof(m_reserved));
+}
+
+uint32_t Pmipv6MagNotifyHeader::Deserialize (Buffer::Iterator start)
+{
+  uint8_t buf[6];
+  Buffer::Iterator i = start;
+  
+  m_nextHeader = i.ReadU8();
+  m_length = i.ReadU8();
+  
+  i.Read(buf, 6);
+  m_macAddress.CopyFrom(buf);
+  
+  m_accessTechnologyType = i.ReadU8();
+  
+  i.Read(m_reserved, sizeof(m_reserved));
+  
+  return GetSerializedSize();
+}
+
+NS_OBJECT_ENSURE_REGISTERED (Pmipv6MagNotifier);
+
+const uint8_t Pmipv6MagNotifier::PROT_NUMBER = 250;
+
+TypeId Pmipv6MagNotifier::GetTypeId ()
+{
+//  static TypeId tid = TypeId ("ns3::Pmipv6MagNotifier")
+//    .SetParent<Ipv6L4Protocol> ()
+//    .AddConstructor<Pmipv6MagNotifier> ()
+//    ;
+  static TypeId tid = TypeId ("ns3::Pmipv6MagNotifier")
+    .SetParent<IpL4Protocol> ()
+    .AddConstructor<Pmipv6MagNotifier> ()
+    ;
+  return tid;
+}
+
+Pmipv6MagNotifier::Pmipv6MagNotifier ()
+  : m_node (0),
+    m_targetAddress ("::")
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Pmipv6MagNotifier::~Pmipv6MagNotifier ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void Pmipv6MagNotifier::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  m_node = 0;
+ // Ipv6L4Protocol::DoDispose ();
+   IpL4Protocol::DoDispose ();
+}
+
+void Pmipv6MagNotifier::NotifyNewAggregate ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (m_node == 0)
+    {
+      Ptr<Node> node = this->GetObject<Node> ();
+      if (node != 0)
+        {
+          Ptr<Ipv6L3Protocol> ipv6 = this->GetObject<Ipv6L3Protocol> ();
+          if (ipv6 != 0)
+            {
+              this->SetNode (node);
+              ipv6->Insert (this);
+            }
+          if (!m_targetAddress.IsAny())
+            {
+              //register linkup callback.
+              uint32_t nDev = node->GetNDevices ();
+              
+              for (uint32_t i = 0; i < nDev; ++i) 
+                {
+                  Ptr<NetDevice> dev = node->GetDevice(i);
+                  Ptr<WifiNetDevice> wDev = dev->GetObject<WifiNetDevice> ();
+                  
+                  if (wDev)
+                    {
+                      Ptr<WifiMac> mac = wDev->GetMac();
+                      Ptr<RegularWifiMac> rmac = mac->GetObject<RegularWifiMac> ();
+                      
+                      if(!mac || !rmac)
+                        {
+                          continue;
+                        }
+                      
+                      rmac->SetNewHostCallback (MakeCallback (&Pmipv6MagNotifier::HandleNewNode, this));
+                      
+                      continue;
+                    }
+                }
+            }
+        }
+    }
+ // Ipv6L4Protocol::NotifyNewAggregate ();
+Object::NotifyNewAggregate ();
+
+}
+
+void Pmipv6MagNotifier::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION (this << node);
+  m_node = node;
+}
+
+Ptr<Node> Pmipv6MagNotifier::GetNode (void)
+{
+  NS_LOG_FUNCTION_NOARGS();
+  return m_node;
+}
+
+int Pmipv6MagNotifier::GetProtocolNumber () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return PROT_NUMBER;
+}
+
+void Pmipv6MagNotifier::SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl)
+{
+  NS_LOG_FUNCTION (this << packet << src << dst << (uint32_t)ttl);
+  
+  Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
+  
+  NS_ASSERT (ipv6 != 0 && ipv6->GetRoutingProtocol () != 0);
+  
+  Ipv6Header header;
+  SocketIpTtlTag tag;
+  Socket::SocketErrno err;
+  Ptr<Ipv6Route> route;
+  Ptr<NetDevice> oif (0); //specify non-zero if bound to a source address
+
+  header.SetDestinationAddress (dst);
+  route = ipv6->GetRoutingProtocol ()->RouteOutput (packet, header, oif, err);
+
+  if (route != 0)
+    {
+      tag.SetTtl (ttl);
+      packet->AddPacketTag (tag);
+      src = route->GetSource ();
+
+      ipv6->Send (packet, src, dst, PROT_NUMBER, route);
+    }
+  else
+    {
+      NS_LOG_LOGIC ("no route.. drop notify message");
+    }  
+}
+enum Ipv6L4Protocol::RxStatus_e Pmipv6MagNotifier::Receive (Ptr<Packet> packet, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << header);
+  return IpL4Protocol::RX_ENDPOINT_UNREACH;
+}
+
+enum IpL4Protocol::RxStatus Pmipv6MagNotifier::Receive (Ptr<Packet> packet, Ipv6Header const &header, Ptr<Ipv6Interface> interface)
+{
+  NS_LOG_FUNCTION (this << packet << header.GetSourceAddress () << header.GetDestinationAddress () << interface);
+  
+  Ptr<Packet> p = packet->Copy ();
+  Pmipv6MagNotifyHeader header;
+  
+  if (!m_newNodeCallback.IsNull ())
+    {
+      p->RemoveHeader(header);
+  
+      m_newNodeCallback (header.GetMacAddress (), 
+	                     Mac48Address::ConvertFrom (interface->GetDevice ()->GetAddress ()), 
+						 header.GetAccessTechnologyType ());
+    }
+
+  return Ipv6L4Protocol::RX_OK;
+}
+
+void Pmipv6MagNotifier::SetTargetAddress(Ipv6Address target)
+{
+  m_targetAddress = target;
+}
+
+Ipv6Address Pmipv6MagNotifier::GetTargetAddress()
+{
+  return m_targetAddress;
+}
+
+void Pmipv6MagNotifier::SetNewNodeCallback (Callback<void, Mac48Address, Mac48Address, uint8_t> cb)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_newNodeCallback = cb;
+}
+
+void Pmipv6MagNotifier::HandleNewNode(Mac48Address from, Mac48Address to, uint8_t att)
+{
+  NS_LOG_FUNCTION (this << from << to << (uint32_t) att );
+  
+  Ptr<Packet> p = Create<Packet>();
+  Pmipv6MagNotifyHeader header;
+  
+  header.SetMacAddress(from);
+  header.SetAccessTechnologyType(att);
+  
+  p->AddHeader(header);
+  
+  SendMessage (p, Ipv6Address::GetAny(), m_targetAddress, 64);
+}
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.h ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-mag-notifier.h	2014-02-03 19:01:52.000000000 +0100
@@ -0,0 +1,145 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef PMIPV6_MAG_NOTIFIER_H
+#define PMIPV6_MAG_NOTIFIER_H
+
+#include "ns3/ipv6-address.h"
+#include "ns3/mac48-address.h"
+#include "ns3/ipv6-l4-protocol.h"
+
+namespace ns3
+{
+
+class Node;
+class Packet;
+
+class Pmipv6MagNotifyHeader : public Header
+{
+public:
+  static TypeId GetTypeId ();
+  virtual TypeId GetInstanceTypeId () const;
+
+  Pmipv6MagNotifyHeader();
+ 
+  virtual ~Pmipv6MagNotifyHeader();
+
+  Mac48Address GetMacAddress() const;
+  void SetMacAddress(Mac48Address macaddr);
+  
+  uint8_t GetAccessTechnologyType() const;
+  void SetAccessTechnologyType(uint8_t att);
+  
+  virtual void Print (std::ostream& os) const;
+  virtual uint32_t GetSerializedSize () const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+ 
+protected:
+
+private:
+  uint8_t m_nextHeader;
+  uint8_t m_length;
+  Mac48Address m_macAddress;
+  uint8_t m_accessTechnologyType;
+  uint8_t m_reserved[7];
+};
+
+class Pmipv6MagNotifier : public Ipv6L4Protocol {
+public:
+  static TypeId GetTypeId ();
+  static const uint8_t PROT_NUMBER;
+  static uint16_t GetStaticProtocolNumber ();
+
+  Pmipv6MagNotifier();
+  
+  virtual ~Pmipv6MagNotifier();
+  
+  void SetNode (Ptr<Node> node);
+
+  Ptr<Node> GetNode (void);
+
+  virtual int GetProtocolNumber () const;
+
+  virtual void NotifyNewAggregate();
+
+  void SendMessage (Ptr<Packet> packet, Ipv6Address src, Ipv6Address dst, uint8_t ttl);
+  virtual enum Ipv6L4Protocol::RxStatus_e Receive (Ptr<Packet> p, Ipv6Address const &src, Ipv6Address const &dst, Ptr<Ipv6Interface> interface);
+  
+
+  void SetTargetAddress(Ipv6Address target);
+  Ipv6Address GetTargetAddress();  
+  
+  void SetNewNodeCallback (Callback<void, Mac48Address, Mac48Address, uint8_t> cb);
+  
+protected:
+  virtual void DoDispose ();
+
+private:
+  void HandleNewNode(Mac48Address from, Mac48Address to, uint8_t att);
+  
+  Ptr<Node> m_node;
+  
+  Ipv6Address m_targetAddress;
+  
+  Callback<void, Mac48Address, Mac48Address, uint8_t> m_newNodeCallback;
+  
+};
+
+} /* namespace ns3 */
+
+#endif /* PMIPV6_MAG_NOTIFIER_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,67 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+ 
+ #include "ns3/log.h"
+ #include "pmipv6-prefix-pool.h"
+ 
+ NS_LOG_COMPONENT_DEFINE( "Pmipv6PrefixPool" );
+ 
+ namespace ns3 
+ {
+ 
+ Pmipv6PrefixPool::Pmipv6PrefixPool(Ipv6Address prefixBegin, uint8_t prefixLen)
+  : m_prefixBegin(prefixBegin),
+    m_prefixBeginLen(prefixLen),
+	m_lastPrefixIndex(0)
+ {
+   NS_LOG_FUNCTION ( this << prefixBegin << (uint32_t) prefixLen);
+   
+   NS_ASSERT ( prefixLen < 64 );
+ }
+ 
+ Ipv6Address Pmipv6PrefixPool::Assign()
+ {
+   NS_LOG_FUNCTION_NOARGS();
+   
+   uint8_t buf[16];
+   Ipv6Address addr;
+   int len;
+   
+   m_prefixBegin.Serialize(buf);
+   
+   len = 8 - m_prefixBeginLen/8;
+   
+   m_lastPrefixIndex++;
+   
+   for ( int i = 0; i < len; i++ )
+     {
+	   buf[7-i] = (uint8_t)((m_lastPrefixIndex >> (i * 8)) & 0xff);
+	 }
+   
+   addr.Set(buf);
+   
+   return addr;
+ }
+ 
+ }
\ Pas de fin de ligne ?? la fin du fichier
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.h ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-prefix-pool.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,51 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef PMIPV6_PREFIX_POOL_H
+#define PMIPV6_PREFIX_POOL_H
+
+#include "ns3/simple-ref-count.h"
+#include "ns3/ipv6-address.h"
+
+namespace ns3
+{
+
+class Pmipv6PrefixPool : public SimpleRefCount<Pmipv6PrefixPool>
+{
+public:
+  Pmipv6PrefixPool(Ipv6Address prefixBegin, uint8_t prefixLen);
+  
+  Ipv6Address Assign();
+protected:
+
+private:
+  Ipv6Address m_prefixBegin;
+  uint8_t m_prefixBeginLen;
+  
+  uint64_t m_lastPrefixIndex;
+};
+
+} /* namespace ns3 */
+
+#endif /* PMIPV6_PREFIX_POOL_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,186 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/uinteger.h"
+#include "ns3/node.h"
+
+#include "pmipv6-profile.h"
+
+NS_LOG_COMPONENT_DEFINE ("Pmipv6Profile");
+
+namespace ns3
+{
+
+NS_OBJECT_ENSURE_REGISTERED (Pmipv6Profile);
+
+TypeId Pmipv6Profile::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::Pmipv6Profile")
+    .SetParent<Object> ()
+	.AddConstructor<Pmipv6Profile>()
+    ;
+  return tid;
+} 
+
+Pmipv6Profile::Pmipv6Profile ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Pmipv6Profile::~Pmipv6Profile ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Flush ();
+}
+
+void Pmipv6Profile::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Flush ();
+  Object::DoDispose ();
+}
+
+Pmipv6Profile::Entry* Pmipv6Profile::Lookup (Identifier id)
+{
+  NS_LOG_FUNCTION (this << id);
+  
+  if ( m_profileList.find (id) != m_profileList.end ())
+    {
+      Pmipv6Profile::Entry* entry = m_profileList[id];
+	  
+	  return entry;
+    }
+  return 0;
+}
+
+Pmipv6Profile::Entry* Pmipv6Profile::Add (Identifier id)
+{
+  NS_LOG_FUNCTION (this << id);
+  NS_ASSERT( m_profileList.find (id) == m_profileList.end() );
+  
+  Pmipv6Profile::Entry* entry = new Pmipv6Profile::Entry (this);
+
+  m_profileList[id] = entry;
+  
+  return entry;
+}
+
+void Pmipv6Profile::Remove (Pmipv6Profile::Entry* entry)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (ProfileListI i = m_profileList.begin () ; i != m_profileList.end () ; i++)
+    {
+      if ((*i).second == entry)
+        {
+          m_profileList.erase (i);
+          delete entry;
+          return;
+        }
+    }
+}
+
+void Pmipv6Profile::Flush ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (ProfileListI i = m_profileList.begin () ; i != m_profileList.end () ; i++)
+    {
+      delete (*i).second; /* delete the pointer Pmipv6Profile::Entry */
+    }
+
+  m_profileList.erase (m_profileList.begin (), m_profileList.end ());
+}
+
+Pmipv6Profile::Entry::Entry (Pmipv6Profile* pf)
+  : m_profile (pf)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+Identifier Pmipv6Profile::Entry::GetMnIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_mnIdentifier;
+}
+
+void Pmipv6Profile::Entry::SetMnIdentifier(Identifier mnId)
+{
+  NS_LOG_FUNCTION ( this << mnId );
+  
+  m_mnIdentifier = mnId;
+}
+
+Identifier Pmipv6Profile::Entry::GetMnLinkIdentifier() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_mnLinkIdentifier;
+}
+
+void Pmipv6Profile::Entry::SetMnLinkIdentifier(Identifier mnLinkId)
+{
+  NS_LOG_FUNCTION ( this << mnLinkId );
+  
+  m_mnLinkIdentifier = mnLinkId;
+}
+
+std::list<Ipv6Address> Pmipv6Profile::Entry::GetHomeNetworkPrefixes() const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  return m_homeNetworkPrefixes;
+}
+
+void Pmipv6Profile::Entry::SetHomeNetworkPrefixes(std::list<Ipv6Address> hnps)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  m_homeNetworkPrefixes = hnps;
+}
+
+void Pmipv6Profile::Entry::AddHomeNetworkPrefix(Ipv6Address hnp)
+{
+  NS_LOG_FUNCTION (this << hnp);
+  
+  m_homeNetworkPrefixes.push_back(hnp);
+}
+
+Ipv6Address Pmipv6Profile::Entry::GetLmaAddress() const
+{
+  NS_LOG_FUNCTION_NOARGS();
+  
+  return m_lmaAddress;
+}
+
+void Pmipv6Profile::Entry::SetLmaAddress(Ipv6Address lmaa)
+{
+  NS_LOG_FUNCTION ( this << lmaa );
+  
+  m_lmaAddress = lmaa;
+}
+
+} /* namespace ns3 */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.h ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/pmipv6-profile.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,106 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef PMIPV6_PROFILE_H
+#define PMIPV6_PROFILE_H
+
+#include <stdint.h>
+
+#include <list>
+
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ptr.h"
+#include "ns3/timer.h"
+#include "ns3/sgi-hashmap.h"
+#include "ns3/identifier.h"
+
+namespace ns3
+{
+
+class Pmipv6Profile : public Object
+{
+public:
+
+  class Entry;
+  
+  /**
+   * \brief Interface ID
+   */
+  static TypeId GetTypeId ();
+
+  Pmipv6Profile();
+  ~Pmipv6Profile();
+  
+  Entry *Lookup(Identifier id);
+  Entry *Add(Identifier id);
+  void Remove(Entry *entry);
+  
+  void Flush();
+  
+  class Entry
+  {
+  public:
+    Entry(Pmipv6Profile *pf);
+	
+    Identifier GetMnIdentifier() const;
+	void SetMnIdentifier(Identifier mnId);
+	
+	Identifier GetMnLinkIdentifier() const;
+	void SetMnLinkIdentifier(Identifier mnLinkId);
+	
+	Ipv6Address GetLmaAddress() const;
+	void SetLmaAddress(Ipv6Address lmaa);
+	
+	std::list<Ipv6Address> GetHomeNetworkPrefixes() const;
+	void SetHomeNetworkPrefixes(std::list<Ipv6Address> hnps);
+	void AddHomeNetworkPrefix(Ipv6Address hnp);
+	
+  protected:
+  
+  private:
+    Pmipv6Profile *m_profile;
+	
+	Identifier m_mnIdentifier;
+	Identifier m_mnLinkIdentifier;
+	Ipv6Address m_lmaAddress;
+	std::list<Ipv6Address> m_homeNetworkPrefixes;
+  };
+protected:
+
+private:
+  typedef sgi::hash_map<Identifier, Pmipv6Profile::Entry *, IdentifierHash> ProfileList;
+  typedef sgi::hash_map<Identifier, Pmipv6Profile::Entry *, IdentifierHash>::iterator ProfileListI;
+  
+  void DoDispose();
+  
+  ProfileList m_profileList;
+
+};
+
+} /* namespace ns3 */
+
+#endif /* PMIPV6_PROFILE_H */
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,296 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+ 
+#include "ns3/log.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+#include "ns3/packet.h"
+#include "ns3/net-device.h"
+#include "ns3/uinteger.h"
+#include "ns3/random-variable.h"
+#include "ns3/inet6-socket-address.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv6-raw-socket-factory.h"
+#include "ns3/ipv6-header.h"
+#include "ns3/icmpv6-header.h"
+#include "ns3/packet-socket-address.h"
+
+#include "unicast-radvd.h"
+
+namespace ns3
+{
+
+NS_LOG_COMPONENT_DEFINE ("UnicastRadvdApplication");
+
+NS_OBJECT_ENSURE_REGISTERED (UnicastRadvd);
+
+TypeId UnicastRadvd::GetTypeId ()
+{
+  static TypeId tid = TypeId ("ns3::UnicastRadvd")
+    .SetParent<Application> ()
+    .AddConstructor<UnicastRadvd> ()
+    ;
+  return tid;
+}
+
+UnicastRadvd::UnicastRadvd ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+UnicastRadvd::~UnicastRadvd ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (RadvdInterfaceListI it = m_configurations.begin () ; it != m_configurations.end () ; ++it)
+    {
+      *it = 0;
+    }
+  m_configurations.clear ();
+  m_socket = 0;
+}
+
+void UnicastRadvd::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  Application::DoDispose ();
+}
+
+void UnicastRadvd::StartApplication ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (!m_socket)
+    {
+      TypeId tid = TypeId::LookupByName ("ns3::PacketSocketFactory");
+      m_socket = Socket::CreateSocket (GetNode (), tid);
+
+      NS_ASSERT (m_socket);
+	  
+	  m_socket->Bind ();
+	  m_socket->ShutdownRecv ();
+    }
+
+  for (RadvdInterfaceListCI it = m_configurations.begin () ; it != m_configurations.end () ; it++)
+    {
+      m_eventIds[(*it)->GetId ()] = EventId ();
+      ScheduleTransmit (Seconds (0.), (*it), m_eventIds[(*it)->GetId ()], Ipv6Address::GetAllNodesMulticast (), true); 
+    }
+}
+
+void UnicastRadvd::StopApplication ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  
+  if (m_socket)
+    {
+	  m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+	}
+
+  for (EventIdMapI it = m_eventIds.begin () ; it != m_eventIds.end () ; ++it)
+    {
+      Simulator::Cancel ((*it).second);
+    }
+  m_eventIds.clear ();
+}
+
+void UnicastRadvd::AddConfiguration (Ptr<UnicastRadvdInterface> routerInterface)
+{
+  NS_LOG_FUNCTION ( this << routerInterface );
+  
+  m_configurations.push_back (routerInterface);
+  
+  if( m_socket )
+    {
+	  NS_LOG_LOGIC ("Application is already started. Adding and Scheduling..");
+	  
+	  if (m_eventIds.find(routerInterface->GetId()) != m_eventIds.end() )
+	    {
+		  m_eventIds[routerInterface->GetId()].Cancel();
+		}
+		
+	  m_eventIds[routerInterface->GetId()] = EventId();
+      ScheduleTransmit (Seconds (0.), routerInterface, m_eventIds[routerInterface->GetId ()], Ipv6Address::GetAllNodesMulticast (), true); 
+	}
+}
+
+void UnicastRadvd::RemoveConfiguration (Ptr<UnicastRadvdInterface> routerInterface)
+{
+  NS_LOG_FUNCTION ( this << routerInterface );
+  
+  if ( m_eventIds.find(routerInterface->GetId()) != m_eventIds.end() )
+    {
+	  m_eventIds[routerInterface->GetId()].Cancel();
+	}
+  
+  m_configurations.remove (routerInterface);
+}
+
+void UnicastRadvd::RemoveConfiguration (int32_t ifIndex)
+{
+  NS_LOG_FUNCTION ( this << ifIndex );
+  
+  for ( RadvdInterfaceListI i = m_configurations.begin(); i != m_configurations.end(); i++ )
+    {
+	  if((*i)->GetId() == (uint32_t)ifIndex)
+	    {
+		  RemoveConfiguration ((*i));
+		  
+		  return;
+		}
+	}
+}
+  
+void UnicastRadvd::ScheduleTransmit (Time dt, Ptr<UnicastRadvdInterface> config, EventId& eventId, Ipv6Address dst, bool reschedule)
+{
+  NS_LOG_FUNCTION (this << dt);
+  eventId = Simulator::Schedule (dt, &UnicastRadvd::Send, this, config, dst, reschedule);
+}
+
+void UnicastRadvd::Send (Ptr<UnicastRadvdInterface> config, Ipv6Address dst, bool reschedule)
+{
+  NS_LOG_FUNCTION (this << dst);
+  NS_ASSERT (m_eventIds[config->GetId ()].IsExpired ());
+  
+  Ipv6Header ipv6Hdr;
+  
+  Icmpv6RA raHdr;
+  Icmpv6OptionLinkLayerAddress llaHdr;
+  Icmpv6OptionMtu mtuHdr;
+  Icmpv6OptionPrefixInformation prefixHdr;
+
+  if (m_eventIds.size () == 0)
+    {
+      return;
+    }
+
+  std::list<Ptr<RadvdPrefix> > prefixes = config->GetPrefixes ();
+  Ptr<Packet> p = Create<Packet> ();
+  Ptr<Ipv6> ipv6 = GetNode ()->GetObject<Ipv6> ();
+
+  /* set RA header information */
+  raHdr.SetFlagM (config->IsManagedFlag ());
+  raHdr.SetFlagO (config->IsOtherConfigFlag ());
+  raHdr.SetFlagH (config->IsHomeAgentFlag ());
+  raHdr.SetCurHopLimit (config->GetCurHopLimit ());
+  raHdr.SetLifeTime (config->GetDefaultLifeTime ());
+  raHdr.SetReachableTime (config->GetReachableTime ());
+  raHdr.SetRetransmissionTime (config->GetRetransTimer ());
+
+  if (config->IsSourceLLAddress ())
+    {
+      /* Get L2 address from NetDevice */
+      Address addr = ipv6->GetNetDevice (config->GetInterface ())->GetAddress ();
+      llaHdr = Icmpv6OptionLinkLayerAddress (true, addr);
+      p->AddHeader (llaHdr);
+    }
+
+  if (config->GetLinkMtu ())
+    {
+      NS_ASSERT (config->GetLinkMtu () >= 1280);
+      mtuHdr = Icmpv6OptionMtu (config->GetLinkMtu ());
+      p->AddHeader (mtuHdr);
+    }
+
+  /* add list of prefixes */
+  for (std::list<Ptr<RadvdPrefix> >::const_iterator jt = prefixes.begin () ; jt != prefixes.end () ; jt++)
+    {
+      uint8_t flags = 0;
+      prefixHdr = Icmpv6OptionPrefixInformation ();
+      prefixHdr.SetPrefix ((*jt)->GetNetwork ());
+      prefixHdr.SetPrefixLength ((*jt)->GetPrefixLength ());
+      prefixHdr.SetValidTime ((*jt)->GetValidLifeTime ());
+      prefixHdr.SetPreferredTime ((*jt)->GetPreferredLifeTime ());
+
+      if ((*jt)->IsOnLinkFlag ())
+        {
+          flags += 1 << 7;
+        }
+
+      if ((*jt)->IsAutonomousFlag ())
+        {
+          flags += 1 << 6;
+        }
+
+      if ((*jt)->IsRouterAddrFlag ())
+        {
+          flags += 1 << 5;
+        }
+
+      prefixHdr.SetFlags (flags);
+
+      p->AddHeader (prefixHdr);
+    }
+
+  Ipv6Address src = ipv6->GetAddress (config->GetInterface (), 0).GetAddress ();
+
+  /* as we know interface index that will be used to send RA and 
+   * we always send RA with router's link-local address, we can 
+   * calculate checksum here.
+   */
+  raHdr.CalculatePseudoHeaderChecksum (src, dst, p->GetSize () + raHdr.GetSerializedSize (), 58 /* ICMPv6 */);
+  p->AddHeader (raHdr);
+
+  ipv6Hdr.SetSourceAddress (src);
+  ipv6Hdr.SetDestinationAddress (dst);
+  ipv6Hdr.SetNextHeader (58 /* ICMPv6 */);
+  ipv6Hdr.SetPayloadLength (p->GetSize());
+  ipv6Hdr.SetHopLimit (255);
+  
+  p->AddHeader (ipv6Hdr);
+  
+  PacketSocketAddress target;
+
+  target.SetSingleDevice(ipv6->GetNetDevice(config->GetInterface())->GetIfIndex());
+  target.SetPhysicalAddress (config->GetPhysicalAddress());
+  target.SetProtocol (0x86dd /* Ipv6 */);
+  
+  Ptr<NetDevice> dev = ipv6->GetNetDevice(config->GetInterface());
+  
+  NS_LOG_LOGIC ("Netdev: " << dev << ", address: " << dev->GetAddress() );
+  
+  /* send RA */
+  NS_LOG_LOGIC ("Send RA");
+  m_socket->SendTo (p, 0, target);
+
+  if (reschedule)
+    {
+      UniformVariable rnd;
+      uint64_t delay = static_cast<uint64_t> (rnd.GetValue (config->GetMinRtrAdvInterval (), config->GetMaxRtrAdvInterval ()) + 0.5);
+      NS_LOG_INFO ("Reschedule in " << delay);
+      Time t = MilliSeconds (delay);
+      ScheduleTransmit (t, config, m_eventIds[config->GetId ()], Ipv6Address::GetAllNodesMulticast (), reschedule);
+    }
+
+}
+
+void UnicastRadvd::HandleRead (Ptr<Socket> socket)
+{
+  NS_LOG_FUNCTION (this << socket);
+
+}
+
+} /* namespace ns3 */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.h ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,146 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef UNICAST_RADVD_H
+#define UNICAST_RADVD_H
+
+#include <map>
+
+#include "ns3/application.h"
+#include "ns3/socket.h"
+
+#include "unicast-radvd-interface.h"
+
+namespace ns3
+{
+
+/**
+ * \ingroup applications 
+ * \defgroup unicastradvd UnicastRadvd
+ */
+
+/**
+ * \ingroup unicast-radvd
+ * \class UnicastRadvd
+ * \brief Router advertisement daemon with MAC unicast.
+ */
+class UnicastRadvd : public Application
+{
+public:
+  /**
+   * \brief Get the type ID.
+   * \return type ID
+   */
+  static TypeId GetTypeId (void);
+
+  /**
+   * \brief Constructor.
+   */
+  UnicastRadvd ();
+
+  /**
+   * \brief Destructor.
+   */
+  virtual ~UnicastRadvd ();
+
+  /**
+   * \brief Default value for maximum delay of RA (ms)
+   */
+  static const uint32_t MAX_RA_DELAY_TIME = 500;
+
+  /**
+   * \brief Add configuration for an interface;
+   * \param routerInterface configuration
+   */
+  void AddConfiguration (Ptr<UnicastRadvdInterface> routerInterface);
+  
+  void RemoveConfiguration (Ptr<UnicastRadvdInterface> routerInterface);
+  void RemoveConfiguration (int32_t ifIndex);
+
+protected:
+  /**
+   * \brief Dispose the instance.
+   */
+  virtual void DoDispose ();
+
+private:
+  typedef std::list<Ptr<UnicastRadvdInterface> > RadvdInterfaceList;
+  typedef std::list<Ptr<UnicastRadvdInterface> >::iterator RadvdInterfaceListI;
+  typedef std::list<Ptr<UnicastRadvdInterface> >::const_iterator RadvdInterfaceListCI;
+
+  typedef std::map<uint32_t, EventId> EventIdMap;
+  typedef std::map<uint32_t, EventId>::iterator EventIdMapI;
+  typedef std::map<uint32_t, EventId>::const_iterator EventIdMapCI;
+
+  /**
+   * \brief Start the application.
+   */
+  virtual void StartApplication ();
+
+  /**
+   * \brief Stop the application.
+   */
+  virtual void StopApplication ();
+
+  /**
+   * \brief Schedule sending a packet.
+   * \param dt interval between packet
+   * \param config interface configuration
+   * \param eventId event ID associated
+   * \param dst IPv6 destination address
+   * \param reschedule if true another send will be reschedule (periodic)
+   */
+  void ScheduleTransmit (Time dt, Ptr<UnicastRadvdInterface> config, EventId& eventId, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast (), bool reschedule = false);
+
+  /**
+   * \brief Send a packet.
+   * \param config interface configuration
+   * \param dst destination address (default ff02::1)
+   * \param reschedule if true another send will be reschedule (periodic)
+   */
+  void Send (Ptr<UnicastRadvdInterface> config, Ipv6Address dst = Ipv6Address::GetAllNodesMulticast (), bool reschedule = false);
+
+  
+  void HandleRead (Ptr<Socket> socket);
+  
+  /**
+   * \brief Raw socket to send RA.
+   */
+  Ptr<Socket> m_socket;
+
+  /**
+   * \brief List of configuration for interface.
+   */
+  RadvdInterfaceList m_configurations;
+
+  /**
+   * \brief Event ID map.
+   */
+  EventIdMap m_eventIds;
+};
+
+} /* namespace ns3 */
+
+#endif /* UNICAST_RADVD_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.cc ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.cc
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.cc	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.cc	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,60 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#include "unicast-radvd-interface.h"
+
+namespace ns3 
+{
+
+uint32_t UnicastRadvdInterface::m_idGen = 1;
+
+UnicastRadvdInterface::UnicastRadvdInterface(uint32_t interface)
+ : RadvdInterface(interface),
+   m_id (m_idGen++)
+{
+}
+
+UnicastRadvdInterface::UnicastRadvdInterface(uint32_t interface, uint32_t maxRtrAdvInterval, uint32_t minRtrAdvInterval)
+ : RadvdInterface(interface, maxRtrAdvInterval, minRtrAdvInterval),
+   m_id (m_idGen++)
+{
+  
+}
+
+Address UnicastRadvdInterface::GetPhysicalAddress() const
+{
+  return m_physicalAddress;
+}
+
+void UnicastRadvdInterface::SetPhysicalAddress( Address addr)
+{
+  m_physicalAddress = addr;
+}
+
+uint32_t UnicastRadvdInterface::GetId () const
+{
+  return m_id;
+}
+
+}
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.h ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.h
--- ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.h	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/model/unicast-radvd-interface.h	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1,63 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Proxy Mobile IPv6 (PMIPv6) (RFC5213) Implementation
+ *
+ * Copyright (c) 2010 KUT, ETRI
+ * (Korea Univerity of Technology and Education)
+ * (Electronics and Telecommunications Research Institute)
+ * 
+ * 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: Hyon-Young Choi <commani@gmail.com>
+ */
+
+#ifndef UNICAST_RADVD_INTERFACE_H
+#define UNICAST_RADVD_INTERFACE_H
+
+#include "ns3/radvd-interface.h"
+
+namespace ns3
+{
+
+/**
+ * \ingroup radvd
+ * \class RadvdInterface
+ * \brief Radvd interface configuration.
+ */
+class UnicastRadvdInterface : public RadvdInterface
+{
+public:
+  UnicastRadvdInterface(uint32_t interface);
+  
+  UnicastRadvdInterface(uint32_t interface, uint32_t maxRtrAdvInterval, uint32_t minRtrAdvInterval);
+  
+  Address GetPhysicalAddress() const;
+  
+  void SetPhysicalAddress(Address addr);
+  
+  uint32_t GetId () const;
+
+private:
+  Address m_physicalAddress;
+  
+  uint32_t m_id;
+  
+  static uint32_t m_idGen;
+  
+};
+
+} /* namespace ns3 */
+
+#endif /* UNICAST_RADVD_INTERFACE_H */
+
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/waf ns-allinone-3.19/ns-3.19/src/pmip6/waf
--- ns-allinone-3.19/ns-3.19/src/pmip6/waf	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/waf	2012-03-02 10:30:00.000000000 +0100
@@ -0,0 +1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
diff -uprN ns-allinone-3.19/ns-3.19/src/pmip6/wscript ns-allinone-3.19/ns-3.19/src/pmip6/wscript
--- ns-allinone-3.19/ns-3.19/src/pmip6/wscript	1970-01-01 01:00:00.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/pmip6/wscript	2014-02-03 18:29:15.000000000 +0100
@@ -0,0 +1,62 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+#PMIPv6 Implementation by CHY
+
+def build(bld):
+    obj = bld.create_ns3_module('pmip6', ['network', 'internet'])
+    obj.source = [
+        'model/binding-cache.cc',
+        'model/binding-update-list.cc',
+		'model/ipv6-mobility-demux.cc',
+		'model/ipv6-mobility-header.cc',
+		'model/ipv6-mobility-l4-protocol.cc',
+		'model/ipv6-mobility-option.cc',
+		'model/ipv6-mobility-option-demux.cc',
+		'model/ipv6-mobility-option-header.cc',
+		'model/ipv6-static-source-routing.cc',
+		'model/ipv6-tunnel-l4-protocol.cc',
+		'model/pmipv6-agent.cc',
+		'model/pmipv6-mag.cc',
+		'model/pmipv6-lma.cc',
+		'model/pmipv6-mag-notifier.cc',
+		'model/pmipv6-prefix-pool.cc',
+		'model/pmipv6-profile.cc',
+		'model/unicast-radvd.cc',
+		'model/unicast-radvd-interface.cc',
+		'model/identifier.cc',
+        'helper/pmip6-helper.cc',
+		'helper/ipv6-static-source-routing-helper.cc',
+        ]
+    headers = bld(features='ns3header')
+    headers.module = 'pmip6'
+    headers.source = [
+        'model/binding-cache.h',
+        'model/binding-update-list.h',
+		'model/ipv6-mobility-demux.h',
+		'model/ipv6-mobility-header.h',
+		'model/ipv6-mobility-l4-protocol.h',
+		'model/ipv6-mobility-option.h',
+		'model/ipv6-mobility-option-demux.h',
+		'model/ipv6-mobility-option-header.h',
+		'model/ipv6-static-source-routing.h',
+		'model/ipv6-tunnel-l4-protocol.h',
+		'model/pmipv6-agent.h',
+		'model/pmipv6-mag.h',
+		'model/pmipv6-lma.h',
+		'model/pmipv6-mag-notifier.h',
+		'model/pmipv6-prefix-pool.h',
+		'model/pmipv6-profile.h',
+		'model/unicast-radvd.h',
+		'model/unicast-radvd-interface.h',
+		'model/identifier.h',
+        'helper/pmip6-helper.h',
+		'helper/ipv6-static-source-routing-helper.h',
+        ]
+
+#    if bld.env['ENABLE_EXAMPLES']:
+#        bld.add_subdirs('examples')
+
+#    bld.ns3_python_bindings()
diff -uprN ns-allinone-3.19/ns-3.19/src/wifi/model/regular-wifi-mac.h ns-allinone-3.19/ns-3.19/src/wifi/model/regular-wifi-mac.h
--- ns-allinone-3.19/ns-3.19/src/wifi/model/regular-wifi-mac.h	2013-12-20 18:44:50.000000000 +0100
+++ ns-allinone-3.19/ns-3.19/src/wifi/model/regular-wifi-mac.h	2014-02-21 07:38:17.670648268 +0100
@@ -230,6 +230,12 @@ public:
   virtual void SetCompressedBlockAckTimeout (Time blockAckTimeout);
   virtual Time GetCompressedBlockAckTimeout (void) const;
 
+  // PMIPv6 Implementation by Andelwahed {
+  virtual void SetNewHostCallback (Callback<void, Mac48Address, Mac48Address, uint8_t> newHost);
+  virtual void SetNewPoaCallback (Callback<void, Mac48Address, Mac48Address, uint8_t> newPoa);
+  // END Implementation
+
+
 protected:
   virtual void DoInitialize ();
   virtual void DoDispose ();
@@ -246,6 +252,12 @@ protected:
   Callback<void> m_linkUp; //!< Callback when a link is up
   Callback<void> m_linkDown; //!< Callback when a link is down
 
+  // PMIPv6 Implementation by Abdelwahed {
+  Callback<void, Mac48Address, Mac48Address, uint8_t> m_newHostCallback;
+  Callback<void, Mac48Address, Mac48Address, uint8_t> m_newPoaCallback;
+  // END Implementation
+
+
   Ssid m_ssid; //!< Service Set ID (SSID)
 
   /** This holds a pointer to the DCF instance for this WifiMac - used

