make it somewhat build sanely
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 05 May 2011 09:28:21 +0200
changeset 66 2fe1f3e576c9
parent 65 227f6347e4e1
child 67 fb900a594421
make it somewhat build sanely
.hgignore
model/netlink-attribute.cc
model/netlink-attribute.h
model/netlink-message-route.cc
model/netlink-message-route.h
model/netlink-message.cc
model/netlink-message.h
model/netlink-socket-address.cc
model/netlink-socket-address.h
model/netlink-socket-factory.cc
model/netlink-socket-factory.h
model/netlink-socket.cc
model/netlink-socket.h
model/ns3-socket-fd-factory.cc
model/ns3-socket-fd-factory.h
netlink/netlink-attribute.cc
netlink/netlink-attribute.h
netlink/netlink-message-route.cc
netlink/netlink-message-route.h
netlink/netlink-message.cc
netlink/netlink-message.h
netlink/netlink-socket-address.cc
netlink/netlink-socket-address.h
netlink/netlink-socket-factory.cc
netlink/netlink-socket-factory.h
netlink/netlink-socket.cc
netlink/netlink-socket.h
ns3waf/__init__.py
ns3waf/__init__.pyc
test/netlink-socket-test.cc
waf
wscript
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,10 @@
+\.rej$
+\.orig$
+\.o$
+~$
+^build
+^objdir
+^elf-cache
+^files-
+^.waf-
+^.lock-
--- a/model/netlink-attribute.cc	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,433 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#include "netlink-attribute.h"
-#include "netlink-message.h"
-#include "netlink-message-route.h"
-#include "ns3/address-utils.h"
-
-namespace ns3 {
-
-
-/***********************************************************************************
-* \ NetlinkAttributeValue
-***********************************************************************************/
-NetlinkAttributeValue::NetlinkAttributeValue ()
-{
-  m_type = UNSPEC;
-  m_u32 = 0;
-}
-
-NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint8_t v)
-{
-  NS_ASSERT (type == U8);
-  m_type = U8;
-  m_u8 = v;
-}
-NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint16_t v)
-{
-  NS_ASSERT (type == U16);
-  m_type = U16;
-  m_u16 = v;
-}
-NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint32_t v)
-{
-  NS_ASSERT (type == U32);
-  m_type = U32;
-  m_u32 = v;
-}
-NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint64_t v)
-{
-  NS_ASSERT (type == U64);
-  m_type = U64;
-  m_u64 = v;
-}
-NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, std::string v)
-{
-  NS_ASSERT (type == STRING);
-  m_type = STRING;
-  m_string = v;
-}
-NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, Address v)
-{
-  NS_ASSERT (type == ADDRESS);
-  m_type = ADDRESS;
-  m_address = v;
-}
-
-void
-NetlinkAttributeValue::SetType (NetlinkAttributeValueType type)
-{
-  m_type = type;
-}
-NetlinkAttributeValueType
-NetlinkAttributeValue::GetType (void) const
-{
-  return m_type;
-}
-void
-NetlinkAttributeValue::SetAddress (Address value)
-{
-  m_address = value;
-}
-void
-NetlinkAttributeValue::SetString (std::string value)
-{
-  m_string = value;
-}
-void
-NetlinkAttributeValue::SetU64 (uint64_t value)
-{
-  m_u64 = value;
-}
-void
-NetlinkAttributeValue::SetU32 (uint32_t value)
-{
-  m_u32 = value;
-}
-void
-NetlinkAttributeValue::SetU16 (uint16_t value)
-{
-  m_u16 = value;
-}
-void
-NetlinkAttributeValue::SetU8 (uint8_t value)
-{
-  m_u8 = value;
-}
-Address
-NetlinkAttributeValue::GetAddress (void) const
-{
-  return m_address;
-}
-std::string
-NetlinkAttributeValue::GetString (void) const
-{
-  return m_string;
-}
-uint64_t
-NetlinkAttributeValue::GetU64 (void) const
-{
-  return m_u64;
-}
-uint32_t
-NetlinkAttributeValue::GetU32 (void) const
-{
-  return m_u32;
-}
-uint16_t
-NetlinkAttributeValue::GetU16 (void) const
-{
-  return m_u16;
-}
-uint8_t
-NetlinkAttributeValue::GetU8 (void) const
-{
-  return m_u8;
-}
-
-void
-NetlinkAttributeValue::Serialize (Buffer::Iterator& start) const
-{
-  uint32_t len;
-
-  if (m_type == U8)
-    {
-      start.WriteU8 (m_u8);
-      len = 1;
-    }
-  else if(m_type == U16)
-    {
-      start.WriteU16 (m_u16);
-      len = 2;
-    }
-  else if(m_type == U32)
-    {
-      start.WriteU32 (m_u32);
-      len = 4;
-    }
-  else if(m_type == STRING)
-    {
-      start.Write ((const uint8_t *)m_string.c_str (), (uint32_t)m_string.size ()+1);
-      len = (uint32_t)m_string.size () + 1;
-    }
-  else if(m_type == ADDRESS)
-    {
-      WriteTo (start, m_address);
-      len = m_address.GetLength ();
-    }
-  else
-    {
-      len = 0;
-    }
-  //netlink align
-  start.WriteU8 (0, NETLINK_MSG_ALIGN (len) - len);
-}
-
-uint32_t
-NetlinkAttributeValue::DeserializeWithType (Buffer::Iterator& start, 
-                                            NetlinkAttributeValueType_e type, uint16_t remaining)
-{
-  uint32_t len =0;
-  m_type = type;  
-
-  if (m_type == U8)
-    {
-      m_u8 = start.ReadU8 ();
-      len = 1;
-    }
-  else if (m_type == U16)
-    {
-      m_u16 = start.ReadU16 ();
-      len = 2;
-    }
-  else if (m_type == U32)
-    {
-      m_u32 = start.ReadU32 ();
-      len = 4;
-    }
-  else if (m_type == U64)
-    {
-      m_u64 = start.ReadU64 ();
-    }  
-  else if (m_type == STRING)
-    {
-      char buf[512];
-      uint32_t i = 0;
-      do 
-      {
-        buf[i] = start.ReadU8 ();
-      } while (buf[i++]);
-      
-      m_string = std::string (buf);
-      len = (uint32_t)m_string.size () + 1;
-    }
-  else if (m_type == ADDRESS)
-    {
-      ReadFrom (start, m_address, remaining);
-      len = m_address.GetLength ();
-    }
-  else
-    {
-      len = 0;
-    }
-
-  //netlink align
-  uint8_t buf[4];
-  start.Read (buf, NETLINK_MSG_ALIGN (len) - len);
-  
-  return NETLINK_MSG_ALIGN (len);
-}
-
-uint32_t
-NetlinkAttributeValue::GetSerializedSize ()const
-{
-  return NETLINK_MSG_ALIGN (GetSize ());
-}
-
-uint32_t
-NetlinkAttributeValue::GetSize () const
-{
-  uint32_t len;
-
-  if (m_type == U8)
-    {
-      len = 1;
-    }
-  else if(m_type == U16)
-    {
-      len =  2;
-    }
-  else if(m_type == U32)
-    {
-      len =  4;
-    }
-  else if (m_type == STRING)
-    {
-      len =  uint32_t (m_string.size () + 1);
-    }
-  else if (m_type == ADDRESS)
-    {
-      len =  m_address.GetLength ();
-    }
-  else
-    {
-      len = 0;
-    }
-
-    return len;
-}
-
-void
-NetlinkAttributeValue::Print (std::ostream &os) const
-{
-  os << "NetlinkAttributeValue (type= " << m_type <<", v= ";
-  if (m_type == U8)
-    {
-      os << m_u8;
-    }
-  else if (m_type == U16)
-    {
-      os << m_u16;
-    }
-  else if (m_type == U32)
-    {
-      os << m_u32;
-    }
-  else if (m_type == U64)
-    {
-      os << m_u64;
-    }  
-  else if (m_type == STRING)
-    {
-      os << m_string;
-    }
-  else if (m_type == ADDRESS)
-    {
-      os << "address(" << m_address <<")";
-    }
-  else
-    {
-      os << "NULL";
-    }
-  os <<")";
-}
-
-
-/***********************************************************************************
-* \ NetlinkAttribute
-***********************************************************************************/
-
-NetlinkAttribute::NetlinkAttribute ()
-  : m_len(4),
-    m_type (0)
-{
-}
-
-NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint8_t payload)
-{
-  m_payload = NetlinkAttributeValue (payloadtype, payload);
-  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
-  m_type = type;
-}
-
-NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint16_t payload)
-{
-  m_payload = NetlinkAttributeValue (payloadtype, payload);
-  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
-  m_type = type;
-}
-NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint32_t payload)
-{
-  m_payload = NetlinkAttributeValue (payloadtype, payload);
-  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
-  m_type = type;;
-}
-NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint64_t payload)
-{
-  m_payload = NetlinkAttributeValue (payloadtype, payload);
-  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
-  m_type = type;
-}
-NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  std::string payload)
-{
-  m_payload = NetlinkAttributeValue (payloadtype, payload);
-  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
-  m_type = type;
-}
-NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  Address payload)
-{
-  m_payload = NetlinkAttributeValue (payloadtype, payload);
-  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
-  m_type = type;
-}
-
-void
-NetlinkAttribute::SetAttrLen (uint16_t v)
-{
-  m_len = v;
-}
-void 
-NetlinkAttribute::SetAttrType (uint16_t v)
-{
-  m_type = v;
-}
-void
-NetlinkAttribute::SetAttrPayload (NetlinkAttributeValue v)
-{
-  m_payload = v;
-}
-uint16_t
-NetlinkAttribute::GetAttrLen () const
-{
-  return m_len;
-}
-uint16_t
-NetlinkAttribute::GetAttrType () const
-{
-  return m_type;
-}
-NetlinkAttributeValue
-NetlinkAttribute::GetAttrPayload() const
-{
-  return m_payload;
-}
-
-void 
-NetlinkAttribute::Print (std::ostream &os) const
-{  
-  os << "NetlinkAttribute "
-     << "len: " << m_len << " "
-     << "type: " << m_type<<" "
-     << "payload:[";
-  m_payload.Print(os);
-  os<<"]";
-}
-
-uint32_t 
-NetlinkAttribute::GetSerializedSize (void) const
-{
-  /* this is the size of an nlattr payload. */
-  return NETLINK_MSG_ATTR_SIZE + m_payload.GetSerializedSize ();
-}
-
-void
-NetlinkAttribute::Serialize (Buffer::Iterator& start) const
-{
-  start.WriteU16 (m_len);
-  start.WriteU16 (m_type);
-  m_payload.Serialize (start);
-}
-
-uint32_t
-NetlinkAttribute::Deserialize (Buffer::Iterator& start, NetlinkAttributeValueType vtypes[])
-{
-  NetlinkAttributeValueType type;
-
-  m_len = start.ReadU16 ();
-  m_type = start.ReadU16 ();
-  type = vtypes[m_type];
-  m_payload.DeserializeWithType (start, type, m_len - 4);
-
-  return GetSerializedSize ();
-}
-
-}; // namespace ns3
--- a/model/netlink-attribute.h	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#ifndef NETLINK_ATTRIBUTE_H
-#define NETLINK_ATTRIBUTE_H
-
-
-#include <stdint.h>
-#include <string>
-#include <ostream>
-#include "ns3/address.h"
-#include "ns3/buffer.h"
-
-namespace ns3 {
-
-/**
-* \brief The Netlink Attribute
-*/
-
-typedef enum NetlinkAttributeValueType_e {
-  UNSPEC, // invalid initial value.
-  U8,
-  U16,
-  U32,
-  U64,
-  STRING,
-  ADDRESS,
-}NetlinkAttributeValueType;
-
-class NetlinkAttributeValue
-{
-public:
-  NetlinkAttributeValue ();
-  NetlinkAttributeValue (NetlinkAttributeValueType type, uint8_t v);
-  NetlinkAttributeValue (NetlinkAttributeValueType type, uint16_t v);
-  NetlinkAttributeValue (NetlinkAttributeValueType type, uint32_t v);
-  NetlinkAttributeValue (NetlinkAttributeValueType type, uint64_t v);
-  NetlinkAttributeValue (NetlinkAttributeValueType type, std::string v);
-  NetlinkAttributeValue (NetlinkAttributeValueType type, Address v);
-  
-  void Serialize (Buffer::Iterator& start) const;
-  uint32_t DeserializeWithType (Buffer::Iterator& start, NetlinkAttributeValueType type, uint16_t remaining);
-  uint32_t GetSerializedSize (void) const;
-  uint32_t GetSize (void) const;
-  void Print (std::ostream &os) const;
-
-  void SetType (NetlinkAttributeValueType type);
-  NetlinkAttributeValueType GetType (void) const;
-  void SetAddress (Address value);
-  void SetString (std::string value);
-  void SetU64 (uint64_t value);
-  void SetU32 (uint32_t value);
-  void SetU16 (uint16_t value);
-  void SetU8 (uint8_t value);
-  Address GetAddress (void) const;
-  std::string GetString (void) const;
-  uint64_t GetU64 (void) const;
-  uint32_t GetU32 (void) const;
-  uint16_t GetU16 (void) const;
-  uint8_t GetU8 (void) const;
-
-private:
-  NetlinkAttributeValueType m_type;
-  uint64_t m_u64;
-  uint32_t m_u32;
-  uint16_t m_u16;
-  uint8_t m_u8;
-  std::string m_string;
-  Address m_address;
-};
-
-struct NetlinkAttribute
-{
-public:
-  NetlinkAttribute ();
-  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint8_t payload);
-  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint16_t payload);
-  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint32_t payload);
-  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint64_t payload);
-  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  std::string payload);
-  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  Address payload);
-
-  //static TypeId GetTypeId (void);
-  //virtual TypeId GetInstanceTypeId (void) const;
-  void Print (std::ostream &os) const;
-  uint32_t GetSerializedSize (void) const;
-  void Serialize (Buffer::Iterator& start) const;
-  uint32_t Deserialize (Buffer::Iterator& start, NetlinkAttributeValueType vtypes[]);
-
-  void SetAttrLen (uint16_t v);
-  void SetAttrType (uint16_t v);
-  void SetAttrPayload (NetlinkAttributeValue v);
-  uint16_t GetAttrLen () const;
-  uint16_t GetAttrType () const;
-  NetlinkAttributeValue GetAttrPayload () const;
-
-private:
-  static const int NETLINK_MSG_ATTR_SIZE = 4; /* size of the nlattr field*/
-  uint16_t m_len;
-  uint16_t m_type; 
-  NetlinkAttributeValue m_payload;
-};
-
-}; // namespace ns3
-
-#endif /* NETLINK_ATTRIBUTE_H */
--- a/model/netlink-message-route.cc	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,647 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#include "netlink-message-route.h"
-#include "netlink-message.h"
-
-namespace ns3 {
-
-/***********************************************************************************
-* \ NetlinkPayload
-***********************************************************************************/
-TypeId 
-NetlinkPayload::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::NetlinkPayload")
-    .SetParent<ObjectBase> ()
-    ;
-  return tid;
-}
-
-
-/***********************************************************************************
-* \ GeneralMessage
-***********************************************************************************/
-
-NS_OBJECT_ENSURE_REGISTERED (GeneralMessage);
-NS_OBJECT_ENSURE_REGISTERED (InterfaceInfoMessage);
-NS_OBJECT_ENSURE_REGISTERED (InterfaceAddressMessage);
-NS_OBJECT_ENSURE_REGISTERED (RouteMessage);
-
-GeneralMessage::GeneralMessage ()
-  : m_family(0)
-{}
-GeneralMessage::~GeneralMessage ()
-{}
-
-void
-GeneralMessage::SetFamily (uint8_t v)
-{
-  m_family = v;
-}
-uint8_t
-GeneralMessage::GetFamily (void) const
-{
-  return m_family;
-}
-
-TypeId 
-GeneralMessage::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::GeneralMessage")
-    .SetParent<NetlinkPayload> ()
-    .AddConstructor<GeneralMessage> ()
-    ;
-  return tid;
-}
-
-TypeId 
-GeneralMessage::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-GeneralMessage::Print (std::ostream &os) const
-{
-  os << " ----GeneralMessage ("
-     << "family: " << (uint32_t)m_family << ")"; 
-}
-
-uint32_t 
-GeneralMessage::GetSerializedSize (void) const
-{
-  /* this is the size of an nlmsghdr payload. */
-  return NETLINK_MSG_ALIGN (NETLINK_GENMSG_SIZE);
-}
-
-
-void
-GeneralMessage::Serialize (Buffer::Iterator& start) const
-{
-  start.WriteU8 (m_family);
-  start.WriteU8 (0, 3);
-}
-
-uint32_t
-GeneralMessage::Deserialize (Buffer::Iterator& start)
-{
-  uint8_t buf[3];
-  m_family = start.ReadU8 ();
-  start.Read (buf, 3);
-  return GetSerializedSize ();
-}
-uint32_t
-GeneralMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
-{
-  uint8_t buf[3];
-  m_family = start.ReadU8 ();
-  start.Read (buf, 3);
-  return GetSerializedSize ();
-}
-
-
-uint32_t
-GeneralMessage::GetNNetlinkAttribute (void)const
-{
-  return m_attributes.size ();
-}
-NetlinkAttribute
-GeneralMessage::GetNetlinkAttribute (uint32_t index)const
-{
-  NS_ASSERT(index < GetNNetlinkAttribute ());
-  return m_attributes[index];
-}
-
-uint32_t
-GeneralMessage::GetAttributeSerializedSize (void) const
-{
-  uint32_t size = 0;
-
-  for (uint32_t i = 0; i < m_attributes.size (); i ++)
-    {
-      size += m_attributes[i].GetSerializedSize ();
-    }
-  return size;
-}
-bool
-GeneralMessage::GetAttributeByType (NetlinkAttribute& attr, uint16_t type)
-{
-  for (uint32_t i = 0; i < m_attributes.size (); i ++)
-    {
-      if (type == m_attributes[i].GetAttrType ())
-        {
-          attr = m_attributes[i];
-          return true;
-        }
-    }
-  return false;  
-}
-void
-GeneralMessage::AppendAttribute (NetlinkAttribute v)
-{
-  m_attributes.push_back (v);
-}
-
-void
-GeneralMessage::SerializeAttribute (Buffer::Iterator& start) const
-{
-  for (uint32_t i = 0; i < m_attributes.size (); i ++)
-    {
-      m_attributes[i].Serialize (start);
-    }
-}
-
-void
-GeneralMessage::PrintAttribute (std::ostream &os) const
-{
-  for (uint32_t i = 0; i < m_attributes.size (); i ++)
-    {
-      os << " ----Attribute (" << i << "):";
-      m_attributes[i].Print(os);
-    }
-}
-
-/***********************************************************************************
-* \ InterfaceInfoMessage
-***********************************************************************************/
-InterfaceInfoMessage::InterfaceInfoMessage ()
-  : m_reserved (0),
-    m_deviceType (0),
-    m_interfaceIndex(0),
-    m_deviceFlags (0),
-    m_changeMask (0)
-{
-  memset ((void*)m_attributeTypes, 0, sizeof (m_attributeTypes));
-  m_attributeTypes[IFL_A_UNSPEC] = UNSPEC;
-  m_attributeTypes[IFL_A_ADDRESS] = ADDRESS;
-  m_attributeTypes[IFL_A_BROADCAST] = ADDRESS;
-  m_attributeTypes[IFL_A_IFNAME] = STRING;
-  m_attributeTypes[IFL_A_MTU] = U32;
-  m_attributeTypes[IFL_A_LINK] = U32;
-  m_attributeTypes[IFL_A_QDISC] = U8;
-  m_attributeTypes[IFL_A_STATS] = UNSPEC;
-  m_attributeTypes[IFL_A_COST] = UNSPEC;
-}
-InterfaceInfoMessage::~InterfaceInfoMessage ()
-{}
-void
-InterfaceInfoMessage::SetDeviceType (uint16_t type)
-{
-  m_deviceType = type;
-}
-void
-InterfaceInfoMessage::SetInterfaceIndex (int32_t index)
-{
-  m_interfaceIndex = index;
-}
-void
-InterfaceInfoMessage::SetDeviceFlags (uint32_t flags)
-{
-  m_deviceFlags = flags;
-}
-void
-InterfaceInfoMessage::SetChangeMask (uint32_t mask)
-{
-  m_changeMask = mask;
-}
-uint16_t
-InterfaceInfoMessage::GetDeviceType (void) const
-{
-  return m_deviceType;
-}
-int32_t
-InterfaceInfoMessage::GetInterfaceIndex (void) const
-{
-  return m_interfaceIndex;
-}
-uint32_t
-InterfaceInfoMessage::GetDeviceFlags (void) const
-{
-  return m_deviceFlags;
-}
-uint32_t
-InterfaceInfoMessage::GetChangeMask (void) const
-{
-  return m_changeMask;
-}
-TypeId 
-InterfaceInfoMessage::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::InterfaceInfoMessage")
-    .SetParent<GeneralMessage> ()
-    .AddConstructor<InterfaceInfoMessage> ()
-    ;
-  return tid;
-}
-TypeId 
-InterfaceInfoMessage::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-InterfaceInfoMessage::Print (std::ostream &os) const
-{  
-  os << " ----InterfaceInfoMessage ("
-     << "deviceType: " << m_deviceType << " "
-     << "interfaceIndex: " << m_interfaceIndex << " "
-     << "deviceFlags: " << m_deviceFlags << " "
-     << "changeMask: " << m_changeMask << ")" ;
-  PrintAttribute (os);
-}
-uint32_t 
-InterfaceInfoMessage::GetSerializedSize (void) const
-{
-  return NETLINK_INTERFACE_SIZE + GetAttributeSerializedSize ();
-}
-
-void
-InterfaceInfoMessage::Serialize (Buffer::Iterator& start) const
-{
-  start.WriteU8 (m_family);
-  start.WriteU8 (m_reserved);
-  start.WriteU16 (m_deviceType);
-  start.WriteU32 (m_interfaceIndex);
-  start.WriteU32 (m_deviceFlags);
-  start.WriteU32 (m_changeMask);
-
-  SerializeAttribute (start);
-}
-uint32_t
-InterfaceInfoMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
-{
-  m_family = start.ReadU8 ();
-  m_reserved = start.ReadU8 ();
-  m_deviceType = start.ReadU16 ();
-  m_interfaceIndex = start.ReadU32 ();
-  m_deviceFlags = start.ReadU32 ();
-  m_changeMask = start.ReadU32 ();
-
-  len -= NETLINK_INTERFACE_SIZE;
-
-  while (len)
-    {
-      NetlinkAttribute attr;
-
-      len -= attr.Deserialize (start, m_attributeTypes);
-      m_attributes.push_back (attr);
-    }
-
-  return GetSerializedSize ();
-}
-
-
-
-/***********************************************************************************
-* \InterfaceAddressMessage
-***********************************************************************************/
-InterfaceAddressMessage::InterfaceAddressMessage ()
-  : m_length (0),
-    m_flags (0),
-    m_scope (0),
-    m_index(0)
-{
-  memset ((void*)m_attributeTypes, 0, sizeof (m_attributeTypes));
-  m_attributeTypes[IF_A_UNSPEC] = UNSPEC;
-  m_attributeTypes[IF_A_ADDRESS] = ADDRESS;
-  m_attributeTypes[IF_A_LOCAL] = ADDRESS;
-  m_attributeTypes[IF_A_LABEL] = STRING;
-  m_attributeTypes[IF_A_BROADCAST] = ADDRESS;
-  m_attributeTypes[IF_A_ANYCAST] = ADDRESS;
-  m_attributeTypes[IF_A_CACHEINFO] = UNSPEC;
-  m_attributeTypes[IF_A_MULTICAST] = ADDRESS;
-}
-InterfaceAddressMessage::~InterfaceAddressMessage ()
-{
-}
-void
-InterfaceAddressMessage::SetFamily (uint8_t family)
-{
-  m_family = family;
-}
-void
-InterfaceAddressMessage::SetLength (uint8_t length)
-{
-  m_length = length;
-}
-void
-InterfaceAddressMessage::SetFlags (uint8_t flags)
-{
-  m_flags = flags;
-}
-void
-InterfaceAddressMessage::SetScope (uint8_t scope)
-{
-  m_scope = scope;
-}
-void
-InterfaceAddressMessage::SetInterfaceIndex (int32_t index)
-{
-  m_index = index;
-}
-
-uint8_t
-InterfaceAddressMessage::GetFamily (void) const
-{
-  return m_family;
-}
-uint8_t
-InterfaceAddressMessage::GetLength (void) const
-{
-  return m_length;
-}
-uint8_t
-InterfaceAddressMessage::GetFlags (void) const
-{
-  return m_flags;
-}
-uint8_t
-InterfaceAddressMessage::GetScope (void) const
-{
-  return m_scope;
-}
-int32_t
-InterfaceAddressMessage::GetInterfaceIndex (void) const
-{
-  return m_index;
-}
-
-TypeId 
-InterfaceAddressMessage::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::InterfaceAddressMessage")
-    .SetParent<GeneralMessage> ()
-    .AddConstructor<InterfaceAddressMessage> ()
-    ;
-  return tid;
-}
-TypeId 
-InterfaceAddressMessage::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-InterfaceAddressMessage::Print (std::ostream &os) const
-{  
-  os << " ----InterfaceAddressMessage ("
-     << "family: " << (uint32_t)m_family << " "
-     << "length: " << (uint32_t)m_length << " "
-     << "flags: " << (uint32_t)m_flags << " "
-     << "scope: " << (uint32_t)m_scope << " "
-     << "index: " << m_index << ")";
-  PrintAttribute (os);
-}
-uint32_t 
-InterfaceAddressMessage::GetSerializedSize (void) const
-{
-  return NETLINK_ADDRESS_SIZE + GetAttributeSerializedSize ();
-}
-
-void
-InterfaceAddressMessage::Serialize (Buffer::Iterator& start) const
-{
-  start.WriteU8 (m_family);
-  start.WriteU8 (m_length);
-  start.WriteU8 (m_flags);
-  start.WriteU8 (m_scope);
-  start.WriteU32 (m_index);
-
-  SerializeAttribute(start);
-}
-
-uint32_t
-InterfaceAddressMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
-{
-  m_family = start.ReadU8 ();
-  m_length = start.ReadU8 ();
-  m_flags = start.ReadU8 ();
-  m_scope = start.ReadU8 ();
-  m_index = start.ReadU32 ();
-
-  len -= NETLINK_ADDRESS_SIZE;
-
-  while (len)
-    {
-      NetlinkAttribute attr;
-
-      len -= attr.Deserialize (start, m_attributeTypes);
-      m_attributes.push_back (attr);
-    }
-
-  return GetSerializedSize ();
-}
-
-
-
-/***********************************************************************************
-* \ RouteMessage
-***********************************************************************************/
-RouteMessage::RouteMessage ()
-  : m_dstLen (0),
-    m_srcLen (0),
-    m_tos (0),
-    m_tableId (0),
-    m_protocol(0),
-    m_scope (0),
-    m_type (0),
-    m_flags (0)
-{
-  memset ((void*)m_attributeTypes, 0, sizeof (m_attributeTypes));
-  m_attributeTypes[RT_A_UNSPEC] = UNSPEC;
-  m_attributeTypes[RT_A_DST] = ADDRESS;
-  m_attributeTypes[RT_A_SRC] = ADDRESS;
-  m_attributeTypes[RT_A_IIF] = U32;
-  m_attributeTypes[RT_A_OIF] = U32;
-  m_attributeTypes[RT_A_GATEWAY] = ADDRESS;
-  m_attributeTypes[RT_A_PRIORITY] = U8;
-  m_attributeTypes[RT_A_PREFSRC] = ADDRESS;
-  m_attributeTypes[RT_A_METRICS] = UNSPEC;
-  //others default value UNSPEC
-}
-RouteMessage::~RouteMessage ()
-{}
-
-void
-RouteMessage::SetFamily (uint8_t v)
-{
-  m_family = v;
-}
-void
-RouteMessage::SetDstLength (uint8_t v)
-{
-  m_dstLen = v;
-}
-void
-RouteMessage::SetSrcLength (uint8_t v)
-{
-  m_srcLen = v;
-}
-void
-RouteMessage::SetTos (uint8_t v)
-{
-  m_tos = v;
-}
-void
-RouteMessage::SetTableId (uint8_t v)
-{
-  m_tableId = v;
-}
-void
-RouteMessage::SetProtocol (uint8_t v)
-{
-  m_protocol = v;
-}
-void
-RouteMessage::SetScope (uint8_t v)
-{
-  m_scope = v;
-}
-void
-RouteMessage::SetType (uint8_t v)
-{
-  m_type = v;
-}
-void
-RouteMessage::SetFlags (uint32_t v)
-{
-  m_flags = v;
-}
-uint8_t
-RouteMessage::GetFamily (void) const
-{
-  return m_family;
-}
-uint8_t
-RouteMessage::GetDstLength (void) const
-{
-  return m_dstLen;
-}
-uint8_t
-RouteMessage::GetSrcLength (void) const
-{
-  return m_srcLen;
-}
-uint8_t
-RouteMessage::GetTos (void) const
-{
-  return m_tos;
-}
-uint8_t
-RouteMessage::GetTableId (void) const
-{
-  return m_tableId;
-}
-uint8_t
-RouteMessage::GetProtocol (void) const
-{
-  return m_protocol;
-}
-uint8_t
-RouteMessage::GetType (void) const
-{
-  return m_type;
-}
-uint8_t
-RouteMessage::GetScope (void) const
-{
-  return m_scope;
-}
-uint32_t
-RouteMessage::GetFlags (void) const
-{
-  return m_flags;
-}
-
-TypeId 
-RouteMessage::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::RouteMessage")
-    .SetParent<GeneralMessage> ()
-    .AddConstructor<RouteMessage> ()
-    ;
-  return tid;
-}
-TypeId 
-RouteMessage::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-RouteMessage::Print (std::ostream &os) const
-{  
-  os << " ----RouteMessage ("
-     << "family: " << (uint32_t)m_family << " "
-     << "dstLen: " << (uint32_t)m_dstLen << " "
-     << "srcLen: " << (uint32_t)m_srcLen << " "
-     << "tos: " << (uint32_t)m_tos << " "
-     << "tableId: " << (uint32_t)m_tableId << " "
-     << "protocol: " << (uint32_t)m_protocol << " "
-     << "scope: " << (uint32_t)m_scope << " "
-     << "type: " << (uint32_t)m_type << " "
-     << "flags: " << m_flags<< ")" ;
-  PrintAttribute (os);
-}
-uint32_t 
-RouteMessage::GetSerializedSize (void) const
-{
-  return NETLINK_ROUTE_SIZE + GetAttributeSerializedSize ();
-}
-
-void
-RouteMessage::Serialize (Buffer::Iterator& start) const
-{
-  start.WriteU8 (m_family);
-  start.WriteU8 (m_dstLen);
-  start.WriteU8 (m_srcLen);
-  start.WriteU8 (m_tos);
-  start.WriteU8 (m_tableId);
-  start.WriteU8 (m_protocol);
-  start.WriteU8 (m_scope);
-  start.WriteU8 (m_type);
-  start.WriteU32 (m_flags);
-
-  SerializeAttribute (start);
-}
-uint32_t
-RouteMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
-{
-  m_family = start.ReadU8 ();
-  m_dstLen = start.ReadU8 ();
-  m_srcLen = start.ReadU8 ();
-  m_tos = start.ReadU8 ();
-  m_tableId = start.ReadU8 ();
-  m_protocol = start.ReadU8 ();
-  m_scope = start.ReadU8 ();
-  m_type = start.ReadU8 ();
-  m_flags = start.ReadU32 ();
-
-  len -= NETLINK_ROUTE_SIZE;
-
-  while (len)
-    {
-      NetlinkAttribute attr;
-
-      len -= attr.Deserialize (start, m_attributeTypes);
-      m_attributes.push_back (attr);
-    }
-
-  return GetSerializedSize ();
-}
-}; // namespace ns3
--- a/model/netlink-message-route.h	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,388 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#ifndef NETLINK_MESSAGE_ROUTE_H
-#define NETLINK_MESSAGE_ROUTE_H
-
-#include "ns3/object-base.h"
-#include "ns3/address.h"
-#include "netlink-attribute.h"
-#include <string>
-
-namespace ns3 {
-
-/*
-* this file define some netlink message of NETLINK_ROUTE protocol,
-* there are mainly three types:interface address, interface info, route entry
-* just implemented them for quagga porting.
-*/
-  
-
-
-/**
-* \Types of messages,here we only define the route message types quagga used
-*/
-enum NetlinkRtmType_e {
-  NETLINK_RTM_BASE = 16,
-
-  NETLINK_RTM_NEWLINK = 16,
-  NETLINK_RTM_DELLINK,
-  NETLINK_RTM_GETLINK,
-  NETLINK_RTM_SETLINK,
-
-  NETLINK_RTM_NEWADDR = 20,
-  NETLINK_RTM_DELADDR,
-  NETLINK_RTM_GETADDR,
-
-  NETLINK_RTM_NEWROUTE = 24,
-  NETLINK_RTM_DELROUTE,
-  NETLINK_RTM_GETROUTE,
-
-  NETLINK_RTM_MAX,
-};  
-
-/**
-* \Types of netlink groups,here we only define types quagga used
-*/
-enum NetlinkRtmGroup_e {
-  NETLINK_RTM_GRP_LINK = 1,
-  NETLINK_RTM_GRP_IPV4_IFADDR = 0x10,
-  NETLINK_RTM_GRP_IPV4_ROUTE = 0x40,
-  RTMGRP_IPV6_IFADDR = 0x100,
-  RTMGRP_IPV6_ROUTE = 0x400,
-};
-
-class NetlinkPayload :public ObjectBase
-{
-public:
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const = 0;
-  virtual void Serialize (Buffer::Iterator& start) const = 0;
-  virtual void Print (std::ostream &os) const = 0;
-  virtual uint32_t GetSerializedSize (void) const = 0;
-};
-
-/***
- General form of address family dependent message.
-
-  struct rtgenmsg
-  {
-    unsigned char		rtgen_family;
-  };
-**/
-
-class GeneralMessage : public NetlinkPayload
-{
-public:
-  GeneralMessage ();
-  virtual ~GeneralMessage ();
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Serialize (Buffer::Iterator& start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator& start);
-  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-
-  
-  virtual uint32_t GetNNetlinkAttribute (void)const;
-  virtual NetlinkAttribute GetNetlinkAttribute (uint32_t index)const;
-  virtual void AppendAttribute (NetlinkAttribute v);
-  virtual void SerializeAttribute (Buffer::Iterator& start) const;
-  virtual void PrintAttribute (std::ostream &os) const;
-  virtual uint32_t GetAttributeSerializedSize (void) const;
-  virtual bool GetAttributeByType (NetlinkAttribute& attr, uint16_t type);
-
-
-  void SetFamily (uint8_t v);
-  uint8_t GetFamily (void) const;
-
-private:
-  static const int NETLINK_GENMSG_SIZE = 1; /* size of the struct rtgenmsg */  
-protected:
-  uint8_t m_family;   //always set to AF_UNSPEC
-  //attribute can exist or not
-  std::vector<NetlinkAttribute> m_attributes;
-};
-
-
-
-/**
-* \brief Link layer specific messages
-*
-* struct ifinfomsg
-* passes link level specific information, not dependent
-* on network protocol.
-*
-  struct ifinfomsg
-  {
-    unsigned char	ifi_family;
-    unsigned char	__ifi_pad;
-    unsigned short	ifi_type;
-    int		ifi_index;	
-    unsigned	ifi_flags;
-    unsigned	ifi_change;
-  };
-*/
-class InterfaceInfoMessage : public GeneralMessage
-{
-public:
-  InterfaceInfoMessage ();
-  virtual ~InterfaceInfoMessage ();
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Serialize (Buffer::Iterator& start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-
-  enum IflAttr_e {
-    IFL_A_UNSPEC,
-    IFL_A_ADDRESS,
-    IFL_A_BROADCAST,
-    IFL_A_IFNAME,
-    IFL_A_MTU,
-    IFL_A_LINK,
-    IFL_A_QDISC,
-    IFL_A_STATS,
-    IFL_A_COST,
-    IFL_A_PRIORITY,
-    IFL_A_MASTER,
-    IFL_A_WIRELESS,		
-    IFL_A_PROTINFO,
-    IFL_A_TXQLEN,
-    IFL_A_MAP,
-    IFL_A_WEIGHT,
-    IFL_A_OPERSTATE,
-    IFL_A_LINKMODE,
-    IFL_A_MAX,
-  };
-
-  enum Type_e {
-    UP = 1,
-    BROADCAST = 2,
-    DBG = 4,
-  };
-
-  void SetDeviceType (uint16_t type);
-  void SetInterfaceIndex (int32_t index);
-  void SetDeviceFlags (uint32_t index);
-  void SetChangeMask (uint32_t mask);
-
-  uint16_t GetDeviceType (void) const;
-  int32_t GetInterfaceIndex (void) const;
-  uint32_t GetDeviceFlags (void) const;
-  uint32_t GetChangeMask (void) const;
-private:
-  static const int NETLINK_INTERFACE_SIZE = 16; /* size of the struct ifinfomsg */
-  uint8_t m_reserved; //not used
-  uint16_t m_deviceType;
-  int32_t m_interfaceIndex;
-  uint32_t m_deviceFlags;
-  uint32_t m_changeMask;
-  NetlinkAttributeValueType m_attributeTypes[IFL_A_MAX];
-};
-
-
-
-
-/**
-* \brief Interface address.
-*
-  struct ifaddrmsg
-  {
-  unsigned char	ifa_family;
-  unsigned char	ifa_prefixlen;
-  unsigned char	ifa_flags;
-  unsigned char	ifa_scope;
-  int		ifa_index;
-  };
-*/
-
-class InterfaceAddressMessage : public GeneralMessage
-{
-public:
-  InterfaceAddressMessage ();
-  virtual ~InterfaceAddressMessage ();
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Serialize (Buffer::Iterator& start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-
-  enum IfAttr_e {
-    IF_A_UNSPEC,
-    IF_A_ADDRESS,
-    IF_A_LOCAL,
-    IF_A_LABEL,
-    IF_A_BROADCAST,
-    IF_A_ANYCAST,
-    IF_A_CACHEINFO,
-    IF_A_MULTICAST,
-    IF_A_MAX
-  };
-
-  enum {
-    F_SECONDARY = 0x01,
-    F_PERMANENT = 0x80,
-    F_DEPRECATED = 0x20,
-    F_TENTATIVE = 0x40
-  };
-  enum {
-    SCOPE_UNIVERSE = 0,
-    SCOPE_SITE = 200,
-    SCOPE_LINK = 253,
-    SCOPE_HOST = 254
-  };
-
-
-  void SetFamily (uint8_t family);
-  void SetLength (uint8_t length);
-  void SetFlags (uint8_t flags);
-  void SetScope (uint8_t scope);
-  void SetInterfaceIndex (int32_t index);
-
-  uint8_t GetFamily (void) const;
-  uint8_t GetLength (void) const;
-  uint8_t GetFlags (void) const;
-  uint8_t GetScope (void) const;
-  int32_t GetInterfaceIndex (void) const;
-
-private:
-  static const int NETLINK_ADDRESS_SIZE = 8; /* size of the struct ifaddrmsg */
-  uint8_t m_length;
-  uint8_t m_flags;
-  uint8_t m_scope;
-  int32_t m_index;
-  NetlinkAttributeValueType m_attributeTypes[IF_A_MAX];
-};
-
-
-/**
-* \brief Definitions used in routing table administration.
-*
-  struct rtmsg
-  {
-    unsigned char		rtm_family;
-    unsigned char		rtm_dst_len;
-    unsigned char		rtm_src_len;
-    unsigned char		rtm_tos;
-
-    unsigned char		rtm_table;	// Routing table id 
-    unsigned char		rtm_protocol;	//Routing protocol; 
-    unsigned char		rtm_scope;	
-    unsigned char		rtm_type;	
-
-    unsigned		rtm_flags;
-  };
-*/
-
-class RouteMessage : public GeneralMessage
-{
-public:
-  RouteMessage ();
-  virtual ~RouteMessage ();
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Serialize (Buffer::Iterator& start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-
-  uint8_t GetFamily (void) const;
-  uint8_t GetDstLength (void) const;
-  uint8_t GetSrcLength (void) const;
-  uint8_t GetTos (void) const;
-  uint8_t GetTableId (void) const;
-  uint8_t GetProtocol(void) const;
-  uint8_t GetType (void) const;
-  uint8_t GetScope (void) const;
-  uint32_t GetFlags (void) const;
-  void SetFamily (uint8_t v);
-  void SetDstLength (uint8_t v);
-  void SetSrcLength (uint8_t v);
-  void SetTos (uint8_t v);
-  void SetTableId (uint8_t v);
-  void SetProtocol (uint8_t v);
-  void SetScope (uint8_t v);
-  void SetType (uint8_t v);
-  void SetFlags (uint32_t v);
-
-  enum RtProtocol_e {
-    RT_PROT_UNSPEC = 0,
-  };
-
-  enum RtFlags_e {
-    RT_F_CLONED = 0x200,
-  };
-
-  enum RtScope_e {
-    RT_SCOPE_UNIVERSE = 0,
-    RT_SCOPE_LINK = 253,
-  };
-
-  enum RtClass_e {
-    RT_TABLE_UNSPEC = 0,
-    RT_TABLE_MAIN = 254,
-  };
-
-  enum RtAttr_e {
-    RT_A_UNSPEC,
-    RT_A_DST,
-    RT_A_SRC,
-    RT_A_IIF,
-    RT_A_OIF,
-    RT_A_GATEWAY,
-    RT_A_PRIORITY,
-    RT_A_PREFSRC,
-    RT_A_METRICS,
-    RT_A_MULTIPATH,
-    RT_A_PROTOINFO,
-    RT_A_FLOW,
-    RT_A_CACHEINFO,
-    RT_A_SESSION,
-    RT_A_MP_ALGO,
-    RT_A_TABLE,
-    RT_A_MAX
-  };
-
-
-private:
-  static const int NETLINK_ROUTE_SIZE = 12; /* size of the struct rtmsg */
-  uint8_t m_dstLen;
-  uint8_t m_srcLen;
-  uint8_t m_tos;
-  uint8_t m_tableId;
-  uint8_t m_protocol;
-  uint8_t m_scope;
-  uint8_t m_type;
-  uint32_t m_flags;
-  NetlinkAttributeValueType m_attributeTypes[RT_A_MAX];
-};
-
-}; // namespace ns3
-
-#endif /* NETLINK_MESSAGE_ROUTE_H */
--- a/model/netlink-message.cc	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,672 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#include "netlink-message.h"
-#include "ns3/address-utils.h"
-#include "ns3/log.h"
-
-NS_LOG_COMPONENT_DEFINE ("NetlinkMessage");
-
-namespace ns3 {
-
-/***********************************************************************************
-* \ NetlinkMessageHeader
-***********************************************************************************/
-NS_OBJECT_ENSURE_REGISTERED (NetlinkMessageHeader);
-NS_OBJECT_ENSURE_REGISTERED (NetlinkMessage);
-
-NetlinkMessageHeader::NetlinkMessageHeader ()
-  : m_nlmsgLen (16),
-    m_nlmsgType (0),
-    m_nlmsgFlags (0),
-    m_nlmsgSeq (0),
-    m_nlmsgPid (0)
-{}
-
-NetlinkMessageHeader::NetlinkMessageHeader (uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid)
-  : m_nlmsgLen (16),
-    m_nlmsgType (type),
-    m_nlmsgFlags (flags),
-    m_nlmsgSeq (seq),
-    m_nlmsgPid (pid)
-{}
-
-void
-NetlinkMessageHeader::SetMsgLen (uint32_t v)
-{
-  m_nlmsgLen = v;
-}
-void
-NetlinkMessageHeader::SetMsgFlags (uint16_t v)
-{
-  m_nlmsgFlags = v;
-}
-void
-NetlinkMessageHeader::SetMsgType (uint16_t v)
-{
-  m_nlmsgType = v;
-}
-void
-NetlinkMessageHeader::SetMsgSeq (uint32_t v)
-{
-  m_nlmsgSeq = v;
-}
-void
-NetlinkMessageHeader::SetMsgPid (uint32_t v)
-{
-  m_nlmsgPid = v;
-}
-uint16_t
-NetlinkMessageHeader::GetMsgFlags (void) const
-{
-  return m_nlmsgFlags;
-}
-uint32_t 
-NetlinkMessageHeader::GetMsgLen (void) const
-{
-  return m_nlmsgLen;
-}
-uint16_t 
-NetlinkMessageHeader::GetMsgType (void) const
-{
-  return m_nlmsgType;
-}
-uint32_t
-NetlinkMessageHeader::GetMsgSeq (void) const
-{
-  return m_nlmsgSeq;
-}
-uint32_t 
-NetlinkMessageHeader::GetMsgPid (void) const
-{
-  return m_nlmsgPid;
-}
-uint32_t
-NetlinkMessageHeader::GetHeaderSize ()
-{
-  return NETLINK_MSG_HEADER_SIZE;
-}
-uint32_t
-NetlinkMessageHeader::GetPayloadSize (void) const
-{
-  return NETLINK_MSG_ALIGN (m_nlmsgLen - NETLINK_MSG_HEADER_SIZE);
-}
-
-TypeId 
-NetlinkMessageHeader::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::NetlinkMessageHeader")
-    .SetParent<Header> ()
-    .AddConstructor<NetlinkMessageHeader> ()
-    ;
-  return tid;
-}
-TypeId 
-NetlinkMessageHeader::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-NetlinkMessageHeader::Print (std::ostream &os) const
-{
-  os << "NetlinkMessageHeader "
-     << "len: " << m_nlmsgLen << " "
-     << "flags: " << m_nlmsgFlags << " "
-     << "type: " << m_nlmsgType << " "
-     << "seq: " << m_nlmsgSeq << " "
-     << "pid: " << m_nlmsgPid;
-}
-
-uint32_t 
-NetlinkMessageHeader::GetSerializedSize (void) const
-{
-  /* this is the size of an nlmsghdr payload. */
-  return NETLINK_MSG_HEADER_SIZE;
-}
-
-void
-NetlinkMessageHeader::Serialize (Buffer::Iterator& start) const
-{
-  start.WriteU32 (m_nlmsgLen);
-  start.WriteU16 (m_nlmsgType);
-  start.WriteU16 (m_nlmsgFlags);
-  start.WriteU32 (m_nlmsgSeq);
-  start.WriteU32 (m_nlmsgPid);
-}
-
-uint32_t
-NetlinkMessageHeader::Deserialize (Buffer::Iterator& start)
-{
-  m_nlmsgLen = start.ReadU32 ();
-  m_nlmsgType = start.ReadU16 ();
-  m_nlmsgFlags = start.ReadU16 ();
-  m_nlmsgSeq = start.ReadU32 ();
-  m_nlmsgPid = start.ReadU32 ();
-
-  return GetSerializedSize ();
-}
-
-
-
-
-/***********************************************************************************
-* \ NetlinkMessageError
-***********************************************************************************/
-
-NetlinkMessageError::NetlinkMessageError ()
-  : m_error (0)
-{
-}
-NetlinkMessageError::~NetlinkMessageError ()
-{}
-void 
-NetlinkMessageError::SetError (int32_t v)
-{
-  m_error = v;
-}
-int32_t
-NetlinkMessageError::GetError (void) const
-{
-  return m_error;
-}
-void
-NetlinkMessageError::SetMsg (NetlinkMessageHeader v)
-{
-  m_msg = v;
-}
-NetlinkMessageHeader
-NetlinkMessageError::GetMsg (void) const
-{
-  return m_msg;
-}
-
-TypeId 
-NetlinkMessageError::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::NetlinkMessageError")
-    .SetParent<NetlinkPayload> ()
-    .AddConstructor<NetlinkMessageError> ()
-    ;
-  return tid;
-}
-
-TypeId 
-NetlinkMessageError::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-void 
-NetlinkMessageError::Print (std::ostream &os) const
-{  
-  os << "----NetlinkMessageError "
-     << "error: " << m_error << " "
-     << "msg:( ";
-  m_msg.Print(os);
-  os << " )";
-}
-
-uint32_t 
-NetlinkMessageError::GetSerializedSize (void) const
-{
-  /* this is the size of an nlmsgerr payload. */
-  return NETLINK_MSG_ERROR_SIZE;
-}
-
-void
-NetlinkMessageError::Serialize (Buffer::Iterator& start) const
-{
-  start.WriteU32 (m_error);
-  m_msg.Serialize (start);
-}
-
-uint32_t
-NetlinkMessageError::Deserialize (Buffer::Iterator& start)
-{  
-  m_error = start.ReadU32 ();
-  m_msg.Deserialize (start);
-  
-  return GetSerializedSize ();
-}
-
-
-
-
-/***********************************************************************************
-* \ NetlinkMessage
-***********************************************************************************/
-NetlinkMessage::NetlinkMessage ()
-{}
-
-void
-NetlinkMessage::SetHeader (NetlinkMessageHeader hdr)
-{
-  m_hdr = hdr;
-}
-NetlinkMessageHeader
-NetlinkMessage::GetHeader (void)const
-{
-  return m_hdr;
-}
-void
-NetlinkMessage::SetGeneralMessage (GeneralMessage genmsg)
-{
-  m_genmsg = genmsg;
-  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + genmsg.GetSerializedSize ());
-}
-void
-NetlinkMessage::SetErrorMessage (NetlinkMessageError errmsg)
-{
-  m_errorMessage = errmsg;
-  m_hdr.SetMsgLen(m_hdr.GetSerializedSize () + errmsg.GetSerializedSize ());
-}
-// the type is one of RTM_NEWLINK,RTM_DELLINK,RTM_GETLINK
-void
-NetlinkMessage::SetInterfaceInfoMessage (InterfaceInfoMessage v)
-{
-  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
-  m_interfaceTemplate = v;
-}
-// the type is one of RTM_NEWADDR,RTM_DELADDR,RTM_GETADDR
-void NetlinkMessage::SetInterfaceAddressMessage (InterfaceAddressMessage v)
-{
-  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
-  m_addressTemplate = v;
-}
-// the type  is one of RTM_NEWROUTE,RTM_DELROUTE,RTM_GETROUTE
-void NetlinkMessage::SetRouteMessage (RouteMessage v)
-{
-  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
-  m_routeTemplate = v;
-}
-GeneralMessage
-NetlinkMessage::GetGeneralMessage (void) const
-{
-  return m_genmsg;
-}
-NetlinkMessageError
-NetlinkMessage::GetErrorMessage (void) const
-{
-  return m_errorMessage;
-}
-InterfaceInfoMessage
-NetlinkMessage::GetInterfaceInfoMessage (void) const
-{
-  return m_interfaceTemplate;
-}
-InterfaceAddressMessage
-NetlinkMessage::GetInterfaceAddressMessage (void) const
-{
-  return m_addressTemplate;
-}
-RouteMessage
-NetlinkMessage::GetRouteMessage (void) const
-{
-  return m_routeTemplate;
-}
-bool
-NetlinkMessage::IsMessageNetlinkControl (uint16_t type)
-{
-  return (type < NETLINK_RTM_BASE);
-}
-bool
-NetlinkMessage::IsMessageNetlinkRoute (uint16_t type)
-{
-  return (type >= NETLINK_RTM_BASE && type < NETLINK_RTM_MAX);
-}
-bool
-NetlinkMessage::IsMessageAddress (uint16_t type)
-{
-  return (type >= NETLINK_RTM_NEWADDR && type <= NETLINK_RTM_GETADDR);
-}
-bool
-NetlinkMessage::IsMessageInterface (uint16_t type)
-{
-  return (type >= NETLINK_RTM_NEWLINK && type <= NETLINK_RTM_SETLINK);
-}
-bool
-NetlinkMessage::IsMessageRoute (uint16_t type)
-{
-  return (type >= NETLINK_RTM_NEWROUTE && type <= NETLINK_RTM_GETROUTE);
-}
-bool
-NetlinkMessage::IsMessageTypeGet (uint16_t type)
-{
-  return ((( type - NETLINK_RTM_BASE)&3) == 2);
-}
-bool
-NetlinkMessage::IsMessageFlagsAck (uint16_t flags)
-{
-  return (flags & NETLINK_MSG_F_ACK) ? true : false;
-}
-bool
-NetlinkMessage::IsMessageFlagsRequest (uint16_t flags)
-{
-  return (flags & NETLINK_MSG_F_REQUEST) ? true : false;
-}
-bool
-NetlinkMessage::IsMessageFlagsDump (uint16_t flags)
-{
-  return (flags & NETLINK_MSG_F_DUMP) ? true : false;
-}
-
-NetlinkMessage::operator MultipartNetlinkMessage (void) const
-{
-  MultipartNetlinkMessage multi_nlmsg;
-  multi_nlmsg.AppendMessage (*this);
-  return multi_nlmsg;
-}
-
-TypeId 
-NetlinkMessage::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::NetlinkMessage")
-    .SetParent<Header> ()
-    .AddConstructor<NetlinkMessage> ()
-    ;
-  return tid;
-}
-TypeId 
-NetlinkMessage::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-
-uint32_t
-NetlinkMessage::GetTotalSize (void) const
-{
-  return NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ());
-}
-
-uint32_t
-NetlinkMessage::GetMsgSize (void) const
-{
-  return m_hdr.GetMsgLen ();
-}
-
-uint32_t
-NetlinkMessage::GetPayloadSize (void) const
-{
-  return m_hdr.GetPayloadSize ();
-}
-uint16_t
-NetlinkMessage::GetMsgType (void) const
-{
-  return m_hdr.GetMsgType ();
-}
-
-uint8_t
-NetlinkMessage::GetFamily(void) const
-{
-  if (IsMessageTypeGet (GetMsgType ()))
-    {
-      NS_LOG_DEBUG ("TypeGetMsg");
-    }
-  if (IsMessageAddress (m_hdr.GetMsgType ()))
-    {
-      return m_addressTemplate.GetFamily ();
-    }
-  else if (IsMessageInterface(m_hdr.GetMsgType ()))
-    {
-      return m_interfaceTemplate.GetFamily ();
-    }
-  else if (IsMessageRoute(m_hdr.GetMsgType ()))
-    {
-      return m_routeTemplate.GetFamily ();
-    }
-  else if (IsMessageFlagsDump (m_hdr.GetMsgFlags ()))
-    {
-      return m_genmsg.GetFamily (); //value is said to be always set to AF_UNSPEC
-    }
-  else
-    {
-      NS_LOG_WARN ("Netlink message type not supported, return AF_UNSPEC");
-      return 0;
-    }
-}
-
-void 
-NetlinkMessage::Print (std::ostream &os) const
-{
-  uint16_t type = m_hdr.GetMsgType ();
-
-  os << "NetlinkMessage  ";
-  os << " ----Header:(";
-  m_hdr.Print(os);
-  os << ")";
-
-  if (type == NETLINK_MSG_DONE )
-    {
-      os << "multipart message ends here";
-    }
-  else if (type == NETLINK_MSG_ERROR )
-    {
-      m_errorMessage.Print (os);
-    }
-  else if (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK)
-    {
-      m_genmsg.Print (os);
-    }  
-  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE)
-    {
-      m_routeTemplate.Print (os);
-    }
-  else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
-    {
-      m_addressTemplate.Print (os);
-    }
-  else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_DELLINK)
-    {
-      m_interfaceTemplate.Print (os);
-    }
-  else
-    {
-      os << "service not supported yet( " << type <<")";
-    }
-}
-uint32_t 
-NetlinkMessage::GetSerializedSize (void) const
-{
-  return NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ());
-}
-
-void
-NetlinkMessage::Serialize (Buffer::Iterator& start) const
-{
-  NS_LOG_FUNCTION (this);
-  //  Print (std::cout);
-  uint16_t type = m_hdr.GetMsgType ();
-
-  m_hdr.Serialize (start);
-
-  if (type == NETLINK_MSG_DONE)
-    {
-      //nothing done
-    }
-  else if (type == NETLINK_MSG_ERROR)
-    {
-      m_errorMessage.Serialize (start);
-    }  
-  else if (NetlinkMessage::IsMessageFlagsDump (m_hdr.GetMsgFlags ()) && 
-           (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK))
-    {
-      m_genmsg.Serialize (start);
-    }  
-  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
-    {
-      m_routeTemplate.Serialize (start);
-    }
-  else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
-    {
-      m_addressTemplate.Serialize (start);
-    }
-  else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_SETLINK)
-    {
-      m_interfaceTemplate.Serialize (start);
-    }
-  else
-    {
-    }  
-}
-
-
-uint32_t
-NetlinkMessage::Deserialize (Buffer::Iterator&start)
-{
-  uint32_t remaining;
-
-  m_hdr.Deserialize (start);
-  remaining = NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ()) - m_hdr.GetSerializedSize ();
-  
-  //Deserialize service module
-  uint16_t type = GetMsgType ();
-  if (remaining)
-    {        
-      if (type == NETLINK_MSG_DONE)
-        {
-          //do nothing
-        }
-      else if (type == NETLINK_MSG_ERROR)
-        {
-          remaining -= m_errorMessage.Deserialize (start);
-        }      
-      else if (NetlinkMessage::IsMessageFlagsDump (m_hdr.GetMsgFlags()) &&
-               (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK))
-        {
-          remaining -= m_genmsg.Deserialize (start, remaining);
-        }
-      else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
-        {
-          remaining -= m_routeTemplate.Deserialize (start, remaining);
-        }
-      else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
-        {
-          remaining -= m_addressTemplate.Deserialize (start, remaining);
-        }
-      else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_SETLINK)
-        {
-          remaining -= m_interfaceTemplate.Deserialize (start, remaining);
-        }
-      else
-        {
-          //do nothing
-        }
-    }
-
-  return GetSerializedSize ();
-}
-
-
-/***********************************************************************************
-* \ MultipartNetlinkMessage
-***********************************************************************************/
-MultipartNetlinkMessage::MultipartNetlinkMessage ()
-{}
-
-TypeId 
-MultipartNetlinkMessage::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::MultipartNetlinkMessage")
-    .SetParent<Header> ()
-    .AddConstructor<MultipartNetlinkMessage> ()
-    ;
-  return tid;
-}
-TypeId 
-MultipartNetlinkMessage::GetInstanceTypeId (void) const
-{
-  return GetTypeId ();
-}
-
-void
-MultipartNetlinkMessage::Print (std::ostream &os) const
-{
-  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
-    {
-      m_netlinkMessages[i].Print (os);
-    }
-}
-uint32_t
-MultipartNetlinkMessage::GetSerializedSize (void) const
-{
-  uint32_t len = 0;
-
-  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
-    {
-      len +=  m_netlinkMessages[i].GetSerializedSize ();
-    }
-  return len;
-}
-void
-MultipartNetlinkMessage::Serialize (Buffer::Iterator start) const
-{
-  NS_LOG_FUNCTION ("Multi" << this);
-  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
-    {
-      m_netlinkMessages[i].Serialize (start);
-    }
-}
-uint32_t
-MultipartNetlinkMessage::Deserialize (Buffer::Iterator start)
-{
-  while (1)
-    {
-      NetlinkMessage nlmsg;
-      nlmsg.Deserialize (start);
-      AppendMessage (nlmsg);
-
-      if (!(nlmsg.GetHeader ().GetMsgFlags () & NETLINK_MSG_F_MULTI))
-        {
-          break;
-        }
-
-      if (nlmsg.GetHeader ().GetMsgType() == NETLINK_MSG_DONE)
-        {
-          break;
-        }
-    }
-  return GetSerializedSize ();
-}
-
-void
-MultipartNetlinkMessage::AppendMessage (NetlinkMessage nlmsg)
-{
-  m_netlinkMessages.push_back (nlmsg);
-}
-
-void
-MultipartNetlinkMessage::Clear ()
-{
-  m_netlinkMessages.clear ();
-}
-
-uint32_t
-MultipartNetlinkMessage::GetNMessages (void) const
-{
-  return m_netlinkMessages.size ();
-}
-NetlinkMessage
-MultipartNetlinkMessage::GetMessage (uint32_t index) const
-{
-  NS_ASSERT(index < m_netlinkMessages.size ());
-  return m_netlinkMessages[index];
-}
-
-}; // namespace ns3
--- a/model/netlink-message.h	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#ifndef NETLINK_MESSAGE_H
-#define NETLINK_MESSAGE_H
-
-#include "ns3/header.h"
-#include "ns3/address.h"
-#include "netlink-message-route.h"
-#include "netlink-attribute.h"
-
-
-namespace ns3 {
-  class NetlinkPayload;
-  class GeneralMessage;
-  class InterfaceAddressMessage;
-  class InterfaceInfoMessage;
-  class RouteMessage;
-  class MultipartNetlinkMessage;
-
-/**
-* \brief The Netlink message structure for an netlink packet
-* 
-There are three levels to a Netlink message: The general Netlink
-message header, the IP service specific template, and the IP service
-specific data.
-
-0                   1                   2                   3
-0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|                                                               |
-|                   Netlink message header                      |
-|                                                               |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|                                                               |
-|                  IP Service Template                          |
-|                                                               |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|                                                               |
-|                  IP Service specific data in TLVs             |
-|                                                               |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-*/
-
-  enum NetlinkMessageFlag
-  {
-    NETLINK_MSG_F_REQUEST = 1,  // It is request message.
-    NETLINK_MSG_F_MULTI = 2,    // Multipart message, terminated by NETLINK_MSG_DONE
-    NETLINK_MSG_F_ACK = 4,      // Reply with ack, with zero or error code
-    NETLINK_MSG_F_ECHO = 8,     // Echo this request 
-
-    /* Modifiers to Get request */
-    NETLINK_MSG_F_ROOT = 0x100,        // specify tree root
-    NETLINK_MSG_F_MATCH = 0x200,       // return all matching
-    NETLINK_MSG_F_ATOMIC = 0x400,      // atomic Get =
-    NETLINK_MSG_F_DUMP = (NETLINK_MSG_F_ROOT|NETLINK_MSG_F_MATCH),
-
-    /* Modifiers to NEW request */
-    NETLINK_MSG_F_REPLACE = 0x100, // Override existing = 
-    NETLINK_MSG_F_EXCL = 0x200,   // Do not touch, if it exists
-    NETLINK_MSG_F_CREATE = 0x400,  // Create, if it does not exist
-    NETLINK_MSG_F_APPEND = 0x800,  // Add to end of list = 
-  };
-
-  enum NetlinkMessageType
-  {
-    NETLINK_MSG_NOOP = 0x1,          // Nothing.
-    NETLINK_MSG_ERROR = 0x2,         // Error
-    NETLINK_MSG_DONE = 0x3,          // End of a dump
-    NETLINK_MSG_OVERRUN = 0x4,       // Data lost
-    NETLINK_MSG_MIN_TYPE = 0x10,     // < 0x10: reserved control messages
-  };
-
-#define NETLINK_MSG_ALIGNTO 4
-#define NETLINK_MSG_ALIGN(X)    (((X)+NETLINK_MSG_ALIGNTO-1) & ~(NETLINK_MSG_ALIGNTO-1) )
-
-class NetlinkMessageHeader : public ObjectBase
-{
-public:
-  NetlinkMessageHeader ();
-  NetlinkMessageHeader (uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid);
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  void Print (std::ostream &os) const;
-  uint32_t GetSerializedSize (void) const;
-  void Serialize (Buffer::Iterator& start) const;
-  uint32_t Deserialize (Buffer::Iterator& start);
-
-  void SetMsgLen (uint32_t v);
-  void SetMsgFlags (uint16_t v);
-  void SetMsgType (uint16_t v);
-  void SetMsgSeq (uint32_t v);
-  void SetMsgPid (uint32_t v);
-  uint32_t GetMsgLen (void) const;
-  uint16_t GetMsgFlags (void) const;
-  uint16_t GetMsgType (void) const;
-  uint32_t GetMsgSeq (void) const;
-  uint32_t GetMsgPid (void) const;
-
-  static uint32_t GetHeaderSize ();
-  uint32_t GetPayloadSize (void) const;
-
-private:
-  static const uint32_t NETLINK_MSG_HEADER_SIZE = 16; /* size of the nlmsghdr field*/
-  uint32_t m_nlmsgLen;	/* Length of message including header */
-  uint16_t m_nlmsgType;	/* Message content */
-  uint16_t m_nlmsgFlags;	/* Additional flags */
-  uint32_t m_nlmsgSeq;	/* Sequence number */
-  uint32_t m_nlmsgPid;	/* Sending process PID */
-};
-
-/**
-* \brief The struct nlmsgerr
-*/
-class NetlinkMessageError : public NetlinkPayload
-{
-public:
-  NetlinkMessageError ();
-  virtual ~NetlinkMessageError();
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Serialize (Buffer::Iterator& start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator& start);
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-
-  void SetError (int32_t v);
-  int32_t GetError (void) const;
-  void SetMsg(NetlinkMessageHeader v);
-  NetlinkMessageHeader GetMsg (void) const;
-
-private:
-  static const int NETLINK_MSG_ERROR_SIZE = 20; /* size of the nlmsgerror field*/
-  int32_t m_error;
-  NetlinkMessageHeader m_msg;        
-};
-
-
-class NetlinkMessage : public ObjectBase
-{
-public:
-  NetlinkMessage ();
-
-  static TypeId GetTypeId (void);
-  TypeId GetInstanceTypeId (void) const;
-  void Print (std::ostream &os) const;
-  uint32_t GetSerializedSize (void) const;
-  void Serialize (Buffer::Iterator& start) const;
-  uint32_t Deserialize (Buffer::Iterator& start);
-
-  operator MultipartNetlinkMessage (void) const;
-
-  uint32_t GetTotalSize (void) const;  //length of netlink message including padding
-  uint32_t GetMsgSize (void) const;    //length of netlink message not including padding
-  uint32_t GetPayloadSize (void) const; //length of message payload
-  uint16_t GetMsgType (void) const;
-  uint8_t GetFamily(void) const;
-
-  void SetHeader (NetlinkMessageHeader hdr);
-  NetlinkMessageHeader GetHeader (void) const;
-
-  //before set message body, should set header first
-  void SetErrorMessage (NetlinkMessageError errmsg);
-  void SetGeneralMessage (GeneralMessage genmsg);
-  void SetInterfaceInfoMessage (InterfaceInfoMessage v);
-  void SetInterfaceAddressMessage (InterfaceAddressMessage v);
-  void SetRouteMessage (RouteMessage v);
-  NetlinkMessageError GetErrorMessage (void) const;
-  GeneralMessage GetGeneralMessage (void) const;
-  InterfaceInfoMessage GetInterfaceInfoMessage (void) const;
-  InterfaceAddressMessage GetInterfaceAddressMessage (void) const;
-  RouteMessage GetRouteMessage (void) const;
-
-  /**
-  * \returns true if type was control type, false otherwise.
-  */
-  static bool IsMessageNetlinkControl (uint16_t type);
-  /**
-  * \returns true if type was netlink route, false otherwise.
-  */
-  static bool IsMessageNetlinkRoute (uint16_t type);
-  static bool IsMessageAddress (uint16_t type);
-  static bool IsMessageInterface (uint16_t type);
-  static bool IsMessageRoute (uint16_t type);
-  /**
-  * \returns true if type was GETxxx , false otherwise.
-  */
-  static bool IsMessageTypeGet (uint16_t type);
-  /**
-  * \returns true if flag has ack , false otherwise.
-  */
-  static bool IsMessageFlagsAck (uint16_t flags);
-  /**
-  * \returns true if flag has request , false otherwise.
-  */
-  static bool IsMessageFlagsRequest (uint16_t flags);
-  /**
-  * \returns true if flag has dump , false otherwise.
-  */
-  static bool IsMessageFlagsDump (uint16_t flags);
-
-private:
-  NetlinkMessageHeader m_hdr;
-
-  //only one type of messages below exists in real world application
-  NetlinkMessageError m_errorMessage;  
-  GeneralMessage m_genmsg;
-  InterfaceInfoMessage m_interfaceTemplate;
-  InterfaceAddressMessage m_addressTemplate;
-  RouteMessage m_routeTemplate;
-};
-
-class MultipartNetlinkMessage : public Header
-{
-public:
-  MultipartNetlinkMessage ();
-
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual void Print (std::ostream &os) const;
-  virtual uint32_t GetSerializedSize (void) const;
-  virtual void Serialize (Buffer::Iterator start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator start);
-
-  void AppendMessage (NetlinkMessage nlmsg);
-  void Clear();
-  uint32_t GetNMessages (void) const;
-  NetlinkMessage GetMessage (uint32_t index) const;
-
-private:
-  std::vector<NetlinkMessage> m_netlinkMessages;
-};
-
-}; // namespace ns3
-
-#endif /* NETLINK_MESSAGE_H */
--- a/model/netlink-socket-address.cc	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/* -*-	Mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#include "netlink-socket-address.h"
-
-namespace ns3 {
-
-NetlinkSocketAddress::NetlinkSocketAddress (uint32_t pid, uint32_t groups)
-  : m_pid(pid),
-    m_groups(groups)
-{}
-
-NetlinkSocketAddress::NetlinkSocketAddress ()
-  : m_pid (0),
-    m_groups (0)
-{}
-
-NetlinkSocketAddress::~NetlinkSocketAddress ()
-{}
-
-void NetlinkSocketAddress::SetProcessID (uint32_t pid)
-{
-  m_pid = pid;
-}
-
-void NetlinkSocketAddress::SetGroupsMask (uint32_t mask)
-{
-  m_groups = mask;
-}
-
-uint32_t NetlinkSocketAddress::GetProcessID (void) const
-{
-  return m_pid;
-}
-
-uint32_t NetlinkSocketAddress::GetGroupsMask (void) const
-{
-  return m_groups;
-}
-
-NetlinkSocketAddress::operator Address (void) const
-{
-  return ConvertTo ();
-}
-
-Address NetlinkSocketAddress::ConvertTo (void) const
-{
-  uint8_t buffer[8];
-
-  buffer[0] = (m_pid >> 24) & 0xff;
-  buffer[1] = (m_pid >> 16) & 0xff;
-  buffer[2] = (m_pid >> 8) & 0xff;
-  buffer[3] = (m_pid >> 0) & 0xff;
-  buffer[4] = (m_groups >> 24) & 0xff;
-  buffer[5] = (m_groups >> 16) & 0xff;
-  buffer[6] = (m_groups >> 8) & 0xff;
-  buffer[7] = (m_groups >> 0) & 0xff;
-
-  return Address (GetType (), buffer, 8);
-}
-
-NetlinkSocketAddress NetlinkSocketAddress::ConvertFrom (const Address &address)
-{
-  NS_ASSERT (IsMatchingType (address));
-
-  NetlinkSocketAddress nl;
-  uint8_t buf[8];
-
-  address.CopyTo (buf);
-
-  nl.m_pid = 0;
-  nl.m_pid |= buf[0];
-  nl.m_pid <<= 8;
-  nl.m_pid |= buf[1];
-  nl.m_pid <<= 8;
-  nl.m_pid |= buf[2];
-  nl.m_pid <<= 8;
-  nl.m_pid |= buf[3];
-
-  nl.m_groups = 0;
-  nl.m_groups |= buf[4];
-  nl.m_groups <<= 8;
-  nl.m_groups |= buf[5];
-  nl.m_groups <<= 8;
-  nl.m_groups |= buf[6];
-  nl.m_groups <<= 8;
-  nl.m_groups |= buf[7];
-
-  return nl;
-}
-
-bool NetlinkSocketAddress::IsMatchingType (const Address &address)
-{
-  return address.IsMatchingType (GetType ());
-}
-
-uint8_t NetlinkSocketAddress::GetType (void)
-{
-  static uint8_t type = Address::Register ();
-  return type;
-}
-
-} // namespace ns3
--- a/model/netlink-socket-address.h	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/* -*-	Mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#ifndef NETLINK_SOCKET_ADDRESS_H
-#define NETLINK_SOCKET_ADDRESS_H
-
-#include "ns3/ptr.h"
-#include "ns3/address.h"
-
-namespace ns3 {
-
-class NetlinkSocketAddress
-{
-public:
-  NetlinkSocketAddress (uint32_t pid, uint32_t groups);
-  NetlinkSocketAddress ();
-  ~NetlinkSocketAddress ();
-
-  void SetProcessID (uint32_t pid);
-  void SetGroupsMask (uint32_t mask);
-
-  uint32_t GetProcessID (void) const;
-  uint32_t GetGroupsMask (void) const;
-
-  /**
-  * \returns an Address instance which represents this
-  * NetlinkSocketAddress instance.
-  */
-  operator Address (void) const;
-  /**
-  * \param address the Address instance to convert from.
-  *
-  * Returns an NetlinkSocketAddress which corresponds to the input
-  * Address
-  */
-  static NetlinkSocketAddress ConvertFrom (const Address &address);
-  /**
-  * \returns true if the address matches, false otherwise.
-  */
-  static bool IsMatchingType (const Address &address);
-private:
-  static uint8_t GetType (void);
-  Address ConvertTo (void) const;
-
-  uint32_t m_pid;
-  uint32_t m_groups;
-
-};
-
-
-} // namespace ns3
-
-#endif /* NETLINK_SOCKET_ADDRESS_H */
--- a/model/netlink-socket-factory.cc	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#include "netlink-socket-factory.h"
-#include "netlink-socket.h"
-#include "ns3/node.h"
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (NetlinkSocketFactory);
-
-TypeId 
-NetlinkSocketFactory::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::NetlinkSocketFactory")
-    .SetParent<SocketFactory> ();
-  return tid;
-}
-
-NetlinkSocketFactory::NetlinkSocketFactory ()
-{}
-
-Ptr<Socket> NetlinkSocketFactory::CreateSocket (void)
-{
-  Ptr<Node> node = GetObject<Node> ();
-  Ptr<NetlinkSocket> socket = CreateObject<NetlinkSocket> ();
-  socket->SetNode (node);
-  return socket;
-} 
-} // namespace ns3
--- a/model/netlink-socket-factory.h	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#ifndef NETLINK_SOCKET_FACTORY_H
-#define NETLINK_SOCKET_FACTORY_H
-
-#include "ns3/socket-factory.h"
-
-namespace ns3 {
-
-class Socket;
-
-/**
- * This can be used as an interface in a node in order for the node to
- * generate NetlinkSockets.
- */
-class NetlinkSocketFactory : public SocketFactory
-{
-public:
-  static TypeId GetTypeId (void);
-
-  NetlinkSocketFactory ();
-
-  /**
-   * Creates a NetlinkSocket and returns a pointer to it.
-   *
-   * \return a pointer to the created socket
-   */
-  virtual Ptr<Socket> CreateSocket (void);
-};
-
-} // namespace ns3
-
-#endif /* NETLINK_SOCKET_FACTORY_H */
--- a/model/netlink-socket.cc	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1571 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-
-#include "netlink-socket.h"
-#include "netlink-socket-address.h"
-#include "netlink-message.h"
-#include "netlink-message-route.h"
-#include "ns3/log.h"
-#include "ns3/node.h"
-#include "ns3/packet.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/simple-net-device.h"
-#include "ns3/uinteger.h"
-#include "ns3/trace-source-accessor.h"
-#include <iostream>
-#include <sstream>
-#include "ns3/ipv6-address.h"
-#include "ns3/ipv6.h"
-#include "ns3/ipv4-l3-protocol.h"
-#include "ns3/ipv4-static-routing-helper.h"
-#include "ns3/ipv4-routing-table-entry.h"
-#include "ns3/ipv6-l3-protocol.h"
-#include "ns3/ipv6-interface.h"
-#include "ns3/ipv6-static-routing-helper.h"
-#include "ns3/ipv6-routing-table-entry.h"
-#include "ns3/socket.h"
-#include "ns3/mac48-address.h"
-#include <sys/socket.h>
-#include <linux/if.h>
-#include <errno.h>
-
-NS_LOG_COMPONENT_DEFINE ("NetlinkSocket");
-
-namespace ns3 {
-
-// GroupSockets store the netlinksocket with noero group value
-// it was due to the mulitcast netlink messages.
-class GroupSockets
-{
-public:
-  static uint32_t GetNSockets(void)
-  { 
-    return m_Sockets.size();
-  }
-  static Ptr<NetlinkSocket> GetSocket(uint32_t index)
-  {
-    NS_ASSERT(index < m_Sockets.size());
-    return m_Sockets[index];
-  }
-  static void AddSocket(Ptr<NetlinkSocket>sock)
-  {
-    m_Sockets.push_back(sock);
-  }
-private:
-   /*use a std::vector to store the sockets with nozero group value*/
-  static std::vector<Ptr<NetlinkSocket> >m_Sockets;
-};
-std::vector<Ptr<NetlinkSocket> >GroupSockets::m_Sockets;
-
-NS_OBJECT_ENSURE_REGISTERED (NetlinkSocket);
-
-/*
-Netlink Socket
-*/
-TypeId
-NetlinkSocket::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::NetlinkSocket")
-    .SetParent<Socket> ()
-    .AddConstructor<NetlinkSocket> ()
-    .AddTraceSource ("Drop", "Drop packet due to receive buffer overflow",
-                     MakeTraceSourceAccessor (&NetlinkSocket::m_dropTrace))
-    .AddAttribute ("RcvBufSize",
-                   "NetlinkSocket maximum receive buffer size (bytes)",
-                   UintegerValue (0xffffffffl),
-                   MakeUintegerAccessor (&NetlinkSocket::m_rcvBufSize),
-                   MakeUintegerChecker<uint32_t> ())
-    .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
-                   CallbackValue (),
-                   MakeCallbackAccessor (&NetlinkSocket::m_icmpCallback),
-                   MakeCallbackChecker ())
-    ;
-  return tid;
-}
-
-NetlinkSocket::NetlinkSocket ()
-  : m_shutdownSend (false),
-    m_shutdownRecv (false),
-    m_rxAvailable (0),
-    m_srcPid (0),
-    m_srcGroups (0),
-    m_dstPid (0),
-    m_dstGroups (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_errno = ERROR_NOTERROR;
-}
-NetlinkSocket::~NetlinkSocket ()
-{
-  NS_LOG_FUNCTION (this);
-}
-void 
-NetlinkSocket::DoDispose (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-int
-NetlinkSocket::ErrnoToSimuErrno (void)
-{
-  switch (m_errno)
-    {
-    case Socket::ERROR_ISCONN:
-      return EISCONN;
-    case Socket::ERROR_NOTCONN:
-      return ENOTCONN;
-    case Socket::ERROR_MSGSIZE:
-      return EMSGSIZE;
-    case Socket::ERROR_AGAIN:
-      return EAGAIN;
-    case Socket::ERROR_SHUTDOWN:
-      return ESHUTDOWN;
-    case Socket::ERROR_OPNOTSUPP:
-      return EOPNOTSUPP;
-    case Socket::ERROR_AFNOSUPPORT:
-      return EAFNOSUPPORT;
-    case Socket::ERROR_INVAL:
-      return EINVAL;
-    case Socket::ERROR_BADF:
-      return EBADF;
-    case Socket::ERROR_NOROUTETOHOST:
-      return EHOSTUNREACH;
-    case Socket::ERROR_NODEV:
-      return ENODEV;
-    case Socket::ERROR_ADDRNOTAVAIL:
-      return EADDRNOTAVAIL;
-    case Socket::SOCKET_ERRNO_LAST:
-    case Socket::ERROR_NOTERROR:
-    default:
-      NS_ASSERT (false);
-      return 0; // quiet compiler
-      break;
-    }
-}
-
-void 
-NetlinkSocket::SetNode (Ptr<Node> node)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = node;
-}
-
-
-enum Socket::SocketErrno
-NetlinkSocket::GetErrno (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_errno;
-}
-enum Socket::SocketType 
-NetlinkSocket::GetSocketType (void) const
-{
-  return Socket::NS3_SOCK_DGRAM;
-}
-
-Ptr<Node>
-NetlinkSocket::GetNode (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_node;
-}
-
-uint32_t
-NetlinkSocket::GetSrcPid (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_srcPid;
-}
-uint32_t
-NetlinkSocket::GetSrcGroups (void)const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_srcGroups;
-}
-uint32_t
-NetlinkSocket::GetDstPid (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_dstPid;
-}
-uint32_t
-NetlinkSocket::GetDstGroups (void)const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_dstGroups;
-}
-
-int
-NetlinkSocket::Bind (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NetlinkSocketAddress address;
-  return DoBind (address);
-}
-int
-NetlinkSocket::Bind (const Address &address)
-{ 
-  NS_LOG_FUNCTION (this << address);
-
-  if (!NetlinkSocketAddress::IsMatchingType (address))
-    {
-      m_errno = ERROR_INVAL;
-      return -1;
-    }
-  NetlinkSocketAddress ad = NetlinkSocketAddress::ConvertFrom (address);
-  return DoBind (ad);
-}
-int
-NetlinkSocket::DoBind (const NetlinkSocketAddress &address)
-{
-  NS_LOG_FUNCTION (this << address);
-
-  m_srcPid = address.GetProcessID ();
-  m_srcGroups = address.GetGroupsMask ();
-
-  if (m_srcGroups)
-    {
-      GroupSockets::AddSocket(this);
-    } 
-  return 0;
-}
-
-int 
-NetlinkSocket::Listen (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_errno = Socket::ERROR_OPNOTSUPP;
-  return -1;
-}
-
-uint32_t
-NetlinkSocket::GetTxAvailable (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return 0;
-}
-uint32_t
-NetlinkSocket::GetRxAvailable (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  // We separately maintain this state to avoid walking the queue 
-  // every time this might be called
-  return m_rxAvailable;
-}
-
-int
-NetlinkSocket::ShutdownSend (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_shutdownSend = true;
-  return 0;
-}
-int
-NetlinkSocket::ShutdownRecv (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_shutdownRecv = true;
-  return 0;
-}
-
-int
-NetlinkSocket::Close (void)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  ShutdownSend();
-  ShutdownRecv();
-  return 0;
-}
-
-int
-NetlinkSocket::Connect (const Address &address)
-{
-  NS_LOG_FUNCTION (this << address);
-  m_errno = Socket::ERROR_OPNOTSUPP;
-  return 0;
-}
-
-Ptr<Packet>
-NetlinkSocket::Recv (uint32_t maxSize, uint32_t flags)
-{
-  NS_LOG_FUNCTION (this << maxSize<< flags);
-  if (m_dataReceiveQueue.empty())
-    {
-      return 0;
-    }
-
-  Ptr<Packet> p = m_dataReceiveQueue.front ();
-  if (p->GetSize () <= maxSize) 
-    {
-      m_dataReceiveQueue.pop ();
-      m_rxAvailable -= p->GetSize ();
-    }
-  else
-    {
-      p = 0; 
-    }
-  return p;
-}
-
-Ptr<Packet>
-NetlinkSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
-{
-  NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
-  Ptr<Packet> packet = Recv (maxSize, flags);
-  if (packet != 0)
-    {
-      SocketAddressTag tag;
-      bool found;
-      found = packet->FindFirstMatchingByteTag (tag);
-      NS_ASSERT (found);
-      fromAddress = tag.GetAddress ();
-    }
-  return packet;
-}
-
-int
-NetlinkSocket::Send (Ptr<Packet> p,uint32_t flags)
-{
-  NS_LOG_FUNCTION (this << p << flags);
-  NetlinkSocketAddress address = NetlinkSocketAddress(m_dstPid, m_dstGroups);
-  return SendTo(p, flags, address);
-}
-
-int
-NetlinkSocket::SendTo (Ptr<Packet> p, uint32_t flags, const Address &toAddress)
-{
-  NS_LOG_FUNCTION (this << p << flags << toAddress);
-  NetlinkSocketAddress ad;
-
-  if (!NetlinkSocketAddress::IsMatchingType (toAddress))
-    {
-      NS_LOG_LOGIC ("ERROR_AFNOSUPPORT");
-      m_errno = ERROR_AFNOSUPPORT;
-      return -1;
-    }
-  ad = NetlinkSocketAddress::ConvertFrom (toAddress);
-  m_dstPid = ad.GetProcessID();
-  m_dstGroups = ad.GetGroupsMask();
-  NS_LOG_INFO ("send netlink message to pid = " << m_dstPid << ", groups = " << m_dstGroups);
-  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending netlink message from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ());
-
-  //Ptr<NetlinkSocket>kernel_socket = GetNetlinkSocketByAddress(ad);
-  //kernel_socket->m_receivedData.push_back(p);
-  //kernel_socket->NotifyDataReceived(p);
-
-  //when netlink socket send packet, the first step is to find the dest netlink socket through address
-  //then send the packet to it. For we partly implement the netlink-family, the dest address
-  //is always the kernel(pid = 0), (Actually, there must be one static kernel netlink socket to
-  //receive/handle messages), we do not setup a kernel socket to receive packet.
-  //
-  
-  MultipartNetlinkMessage multipartnlmsg;
-  uint32_t packet_len, remain_len;
-
-  packet_len = p->GetSize ();
-  remain_len = packet_len;
-
-  while (remain_len > NetlinkMessageHeader::GetHeaderSize ())
-    {
-      remain_len -= p->RemoveHeader (multipartnlmsg);
-      NS_ASSERT (remain_len == p->GetSize ());
-
-      //actually, message to kernel contains single one netlink message
-      for (uint32_t i = 0; i < multipartnlmsg.GetNMessages(); i ++)
-        {
-          NetlinkMessage nlmsg = multipartnlmsg.GetMessage (i);
-          if (HandleMessage (nlmsg) < 0)
-            {
-              if (m_errno)
-                {
-                  SendAckMessage (nlmsg, -ErrnoToSimuErrno ());
-                }
-            }
-          else if (NetlinkMessage::IsMessageFlagsAck (nlmsg.GetHeader ().GetMsgFlags ()))
-            {
-              SendAckMessage (nlmsg, 0);
-            }
-        }
-    }
-
-  NotifyDataSent (packet_len);
-  NS_LOG_INFO ("netlink socket kernel error " << -m_errno);
-  return packet_len;
-}
-
-int
-NetlinkSocket::GetSockName (Address &address) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NetlinkSocketAddress ad;
-
-  ad.SetProcessID (GetSrcPid ());
-  ad.SetGroupsMask (GetSrcGroups ());
-  address = ad;
-  return 0;
-}
-int
-NetlinkSocket::GetPeerName (Address &address) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  // XXX
-  NS_ASSERT (false);
-  return -1;
-}
-bool 
-NetlinkSocket::SetAllowBroadcast (bool allowBroadcast)
-{
-  NS_ASSERT (false);
-  return false;
-}
-bool 
-NetlinkSocket::GetAllowBroadcast () const
-{
-  NS_ASSERT (false);
-  return false;
-}
-
-
-void
-NetlinkSocket::ForwardUp (Ptr<Packet> packet, NetlinkSocketAddress &address)
-{
-  NS_LOG_FUNCTION (this << packet << address);
-
-  if (m_shutdownRecv)
-    {
-      return;
-    }
-  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
-    {
-      SocketAddressTag tag;
-      tag.SetAddress (address);
-      packet->AddByteTag (tag);
-      m_dataReceiveQueue.push (packet);
-      m_rxAvailable += packet->GetSize ();
-      NotifyDataRecv ();
-    }
-  else
-    {
-      NS_LOG_WARN ("No receive buffer space available.  Drop.");
-      m_dropTrace (packet);
-    }
-}
-
-int32_t
-NetlinkSocket::SendMessageUnicast (const MultipartNetlinkMessage &nlmsg, uint32_t pid, int32_t nonblock)
-{
-  NS_LOG_FUNCTION (this << pid << nonblock);
-  //here we send message instantly
-  Ptr<Packet> p = Create<Packet> ();
-  p->AddHeader (nlmsg);
-
-  NetlinkSocketAddress address;
-  address.SetProcessID (pid);
-
-  //send packet to user space
-  ForwardUp (p, address);
-  return 0;
-}
-int32_t
-NetlinkSocket::SendMessageBroadcast (const MultipartNetlinkMessage &nlmsg, 
-                                     uint32_t pid, 
-                                     uint32_t group,
-                                     Ptr<Node> node)
-{
-  NS_LOG_FUNCTION ("SendMessageBroadcast" << pid << group);
-  //fisrt find the dest netlink socket through group value, then attach this nlmsg to its recv-queue
-  for (uint32_t i = 0; i < GroupSockets::GetNSockets (); i ++)
-    {
-      Ptr<NetlinkSocket> nlsock = GroupSockets::GetSocket (i);
-
-      if ((nlsock->GetSrcGroups () & group) &&
-          (nlsock->GetSrcPid () != pid) &&
-          node == nlsock->GetNode ())
-        {
-          //here we send message instantly
-          Ptr<Packet> p = Create<Packet> ();
-          p->AddHeader (nlmsg);
-
-          NetlinkSocketAddress address;
-          address.SetProcessID (nlsock->GetSrcPid());
-          address.SetGroupsMask (group);
-
-          //send packet to user space
-          nlsock->ForwardUp (p, address);
-        }
-    }
-  return 0;
-}
-void
-NetlinkSocket::SendAckMessage (const NetlinkMessage&nlmsg, int32_t err)
-{
-  NS_LOG_FUNCTION (this << err);
-  NetlinkMessageHeader rep;
-  NetlinkMessage ackmsg;
-  NetlinkMessageError errmsg;
-
-  rep.SetMsgPid (nlmsg.GetHeader ().GetMsgPid ());
-  rep.SetMsgSeq (nlmsg.GetHeader ().GetMsgSeq ());
-  rep.SetMsgType (NETLINK_MSG_ERROR);
-  rep.SetMsgFlags (0);
-
-  errmsg.SetError (err);
-  //kernel send the whole nlmsg back if error != 0, here we just send the header back
-  errmsg.SetMsg (nlmsg.GetHeader ());
-
-  //then send errmsg back to user space
-  ackmsg.SetHeader (rep);
-  ackmsg.SetErrorMessage (errmsg);
-
-  SendMessageUnicast (ackmsg, rep.GetMsgPid (), 1);
-}
-
-int32_t
-NetlinkSocket::HandleMessage (const NetlinkMessage&nlmsg)
-{
-  NS_LOG_FUNCTION (this);
-  uint16_t type = nlmsg.GetMsgType ();
-  NetlinkMessageHeader nhr = nlmsg.GetHeader ();
-
-  if (nhr.GetMsgLen () < NetlinkMessageHeader::GetHeaderSize ())
-    {
-      m_errno = ERROR_INVAL;
-      return -1;
-    }
-
-  if (NetlinkMessage::IsMessageNetlinkControl (type))
-    {
-      NS_LOG_INFO ("netlink control message type not parsed in kernel");
-      return 0;
-    }
-  else if (NetlinkMessage::IsMessageNetlinkRoute (type))
-    {
-      return HandleNetlinkRouteMessage (nlmsg);
-    }
-  else
-    {
-      NS_LOG_INFO ("netlink message type not parsed in kernel");
-      m_errno = ERROR_INVAL;
-      return -1;
-    }  
-}
-
-int32_t
-NetlinkSocket::HandleNetlinkRouteMessage (const NetlinkMessage &nlmsg)
-{
-  NS_LOG_FUNCTION (this);
-  uint8_t family;
-  int16_t type;
-  int32_t err;
-
-  /* Only requests are handled by kernel now */
-  if (!NetlinkMessage::IsMessageFlagsRequest (nlmsg.GetHeader ().GetMsgFlags ()))
-    return 0;
-
-  type = nlmsg.GetMsgType ();
-
-  /* A control message: ignore them */
-  if (NetlinkMessage::IsMessageNetlinkControl (type))
-    {
-      return 0;
-    }
-  else if (NetlinkMessage::IsMessageNetlinkRoute (type))
-    {
-      /* All the messages must have at least 1 byte length */
-      if (nlmsg.GetPayloadSize () < 1)
-        return 0;
-
-      family = nlmsg.GetFamily ();
-      /*here we do not deal with different family, default for AF_NET*/
-      NS_ASSERT(family == AF_INET || family == AF_UNSPEC || family == AF_PACKET || family == AF_INET6);  
-
-      /*for GET*** message, dump it to userspace*/
-      if (NetlinkMessage::IsMessageTypeGet (type) && 
-          NetlinkMessage::IsMessageFlagsDump (nlmsg.GetHeader ().GetMsgFlags ())) 
-        {
-          DumpNetlinkRouteMessage (nlmsg, type, family);
-          return -1;
-        }
-
-      /* other types of messages*/
-      return DoNetlinkRouteMessage (nlmsg, type, family);
-    }
-  else/* Unknown message: reply with EINVAL */
-    {
-      err = ERROR_INVAL;
-      return -1;
-    } 
-}
-
-int32_t
-NetlinkSocket::DumpNetlinkRouteMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << type << family);
-
-  NS_ASSERT (type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETLINK);
-
-  MultipartNetlinkMessage nlmsg_dump;
-  NetlinkMessageHeader nhr = nlmsg.GetHeader ();
-  int32_t err;
-
-  if (type == NETLINK_RTM_GETADDR)
-    {
-      nlmsg_dump = BuildInterfaceAddressDumpMessage (m_srcPid, nhr.GetMsgSeq(), family);
-    }
-  else if (type == NETLINK_RTM_GETLINK)
-    {
-      nlmsg_dump = BuildInterfaceInfoDumpMessage (m_srcPid, nhr.GetMsgSeq(), family);      
-    }
-  else if (type == NETLINK_RTM_GETROUTE)
-    {
-      nlmsg_dump = BuildRouteDumpMessage (m_srcPid, nhr.GetMsgSeq(), family);
-    }
-  else
-    {
-      m_errno = ERROR_INVAL;
-      return -1;
-    }
-
-  //then append netlink message with type NLMSG_DONE
-  NetlinkMessage nlmsg_done;
-  NetlinkMessageHeader nhr2 = NetlinkMessageHeader (NETLINK_MSG_DONE, NETLINK_MSG_F_MULTI, 
-                                                   nlmsg.GetHeader ().GetMsgSeq (), m_srcPid);
-  nlmsg_done.SetHeader (nhr2);
-  //kernel append nlmsg_dump size to it, here we omit it
-  nlmsg_dump.AppendMessage (nlmsg_done);
-
-  err = SendMessageUnicast (nlmsg_dump, m_srcPid, 1);
-  return err;
-}
-
-/*here only for ADD/DEL/GET*** types*/
-int32_t
-NetlinkSocket::DoNetlinkRouteMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << type <<family);
-  int32_t err;
-
-  if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
-    {      
-      err = DoInterfaceAddressMessage (nlmsg, type, family);
-    }
-  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
-    {     
-      err = DoRouteMessage (nlmsg, type, family);
-    }
-  else if (type == NETLINK_RTM_GETLINK || type == NETLINK_RTM_SETLINK)
-    {     
-      err = DoInterfaceInfoMessage (nlmsg, type, family);
-    }
-  else
-    {
-      NS_LOG_LOGIC ("netlink message:type( " << type << ") not processed by ns3 now." );
-      m_errno = ERROR_INVAL;
-      err = -1;
-    } 
-  
-  return err;
-}
-
-MultipartNetlinkMessage
-NetlinkSocket::BuildInterfaceAddressDumpMessage (uint32_t pid, uint32_t seq, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << pid << seq <<family);
-  MultipartNetlinkMessage nlmsg_dump;
-  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
-
-  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i ++)
-    {
-      if (!ipv4->IsUp (i))
-        continue;
-
-      Ipv4Address addri = ipv4->GetAddress (i, 0).GetLocal ();
-      Ipv4Mask maski = ipv4->GetAddress (i, 0).GetMask ();
-      Ipv4Address bcast = ipv4->GetAddress (i, 0).GetBroadcast ();
-
-      //here get the address mask length
-      uint32_t mask = maski.Get ();
-      uint8_t mask_len = 0;
-      while (mask)
-        {
-          mask = mask << 1;
-          mask_len ++;
-        }
-      
-      //next fill the message body
-      NetlinkMessage nlmsg_ifa;
-      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWADDR, NETLINK_MSG_F_MULTI, seq, pid);
-      InterfaceAddressMessage ifamsg;
-
-      ifamsg.SetInterfaceIndex (i);
-      ifamsg.SetFamily (AF_INET);//default AF_INET      
-      ifamsg.SetLength (mask_len);
-      ifamsg.SetFlags (0);
-      ifamsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
-
-      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LOCAL,    ADDRESS, addri));
-      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ADDRESS,  ADDRESS, addri));
-      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_BROADCAST,ADDRESS, bcast));
-      //      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LABEL,    STRING,  "ns3-ifaddr"));//not used in ns3
-      //ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ANYCAST,  ADDRESS, Ipv4Address("0.0.0.0")));//not used in ns3
-      //XXXother attributes not used by ns3
-
-      nlmsg_ifa.SetHeader(nhr);
-      nlmsg_ifa.SetInterfaceAddressMessage (ifamsg);
-      nlmsg_dump.AppendMessage (nlmsg_ifa);
-    }
-
-  // For IPv6
-  Ptr<Ipv6>ipv6 = m_node->GetObject<Ipv6> ();
-
-  for (uint32_t i = 0; i < ipv6->GetNInterfaces(); i ++)
-    {
-      if (!ipv6->IsUp (i))
-        continue;
-
-      for (uint32_t j = 0; j < ipv6->GetNAddresses(i); j ++)
-        {
-          Ipv6Address addri = ipv6->GetAddress (i, j).GetAddress();
-          Ipv6Prefix prefix = ipv6->GetAddress (i, j).GetPrefix ();
-
-          //here get the address mask length
-          uint8_t mask_len = prefix.GetPrefixLength();
-
-          //loopback address's prefix is wrong... FIXME
-          if (addri.IsEqual(Ipv6Address::GetLoopback()))
-            mask_len = 128;
-      
-          //next fill the message body
-          NetlinkMessage nlmsg_ifa;
-          NetlinkMessageHeader nhr = NetlinkMessageHeader(NETLINK_RTM_NEWADDR, NETLINK_MSG_F_MULTI, seq, pid);
-          InterfaceAddressMessage ifamsg;       
-
-          ifamsg.SetInterfaceIndex(i);
-          ifamsg.SetFamily(AF_INET6);
-          ifamsg.SetFlags(0);
-
-
-          if (addri.IsLinkLocal())
-            {
-              ifamsg.SetLength(64);
-              ifamsg.SetScope (RouteMessage::RT_SCOPE_LINK);
-            }
-          else
-            {
-              ifamsg.SetLength(mask_len);
-              ifamsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
-            }
-
-
-          ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LOCAL,    ADDRESS, addri));
-          ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ADDRESS,  ADDRESS, addri));
-          //XXXother attributes not used by ns3
-
-          nlmsg_ifa.SetHeader(nhr);
-          nlmsg_ifa.SetInterfaceAddressMessage (ifamsg);
-          nlmsg_dump.AppendMessage (nlmsg_ifa);
-        }
-    }
-  return nlmsg_dump;
-}
-MultipartNetlinkMessage
-NetlinkSocket::BuildInterfaceInfoDumpMessage (uint32_t pid, uint32_t seq, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << pid << seq <<family);
-  MultipartNetlinkMessage nlmsg_dump;
-  for (uint32_t i = 0; i < m_node->GetNDevices (); i ++)
-    {
-      Ptr<NetDevice> dev = m_node->GetDevice (i);
-      Address mac;
-      Address bcast;
-      uint32_t mtu;
-      uint32_t flags = 0;
-
-      mac = dev->GetAddress ();
-      bcast = dev->GetBroadcast ();
-      mtu = (uint32_t)dev->GetMtu ();
-
-      if (dev->IsLinkUp ())
-        {
-          flags |= IFF_RUNNING;
-          flags |= IFF_UP;
-        }
-      if (dev->IsBroadcast ())
-        {
-          flags |= IFF_BROADCAST;
-        }
-      if (dev->IsMulticast ())
-        {
-          flags |= IFF_MULTICAST;
-        }
-
-      NetlinkMessage nlmsg_ifinfo;
-      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWLINK, NETLINK_MSG_F_MULTI, seq, pid);
-      InterfaceInfoMessage ifinfomsg;     
-
-      ifinfomsg.SetFamily(0);      // AF_UNSPEC
-      ifinfomsg.SetDeviceType (0); // not clear
-      ifinfomsg.SetInterfaceIndex (i);
-      ifinfomsg.SetDeviceFlags (flags); // not clear
-      ifinfomsg.SetChangeMask (0xffffffff);
-
-      // the ns3 device have no  name, here we set "ns3-device i" for test
-      std::stringstream ss;
-      ss <<  "ns3-device" << i;
-
-      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_IFNAME,    STRING,  ss.str()));
-      //not used in ns3
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_TXQLEN,    U32,     0));
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_WEIGHT,    U32,     0));
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_OPERSTATE, U8,      0));
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_LINKMODE,  U8,      0));
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_MAP,       UNSPEC,  0));
-      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_ADDRESS,   ADDRESS, mac));
-      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_BROADCAST, ADDRESS, bcast));
-      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_MTU,       U32,     mtu));
-      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_LINK,      U32,     i));
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_QDISC,     STRING,  ""));
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_MASTER,    U32,     0));
-      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_STATS,     UNSPEC,  0));
-
-      nlmsg_ifinfo.SetHeader (nhr);
-      nlmsg_ifinfo.SetInterfaceInfoMessage (ifinfomsg);
-      nlmsg_dump.AppendMessage (nlmsg_ifinfo);
-    }
-  return nlmsg_dump;
-}
-MultipartNetlinkMessage
-NetlinkSocket::BuildRouteDumpMessage (uint32_t pid, uint32_t seq, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << pid << seq <<family);
-  MultipartNetlinkMessage nlmsg_dump;
-  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
-
-  // We only care about staticRouting for netlink support
-  Ipv4StaticRoutingHelper routingHelper;
-  Ptr<Ipv4StaticRouting> ipv4Static = routingHelper.GetStaticRouting (ipv4);
-  for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); i ++)
-    {
-      NetlinkMessage nlmsg_rt;
-      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, NETLINK_MSG_F_MULTI, seq, pid);
-      RouteMessage rtmsg;
-      Ipv4RoutingTableEntry route = ipv4Static->GetRoute (i);
-
-      rtmsg.SetFamily (AF_INET);
-      rtmsg.SetDstLength (32);
-      rtmsg.SetSrcLength (0);
-      rtmsg.SetTos (0);//not clear
-      rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
-      rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
-      rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
-      rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
-
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
-      // ns3 use local address as the route src address
-      //      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, route.GetSource()));
-      //      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, route.GetSource()));//not used in ns3
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface ()));
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface ()));      
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway ()));
-
-      nlmsg_rt.SetHeader (nhr);
-      nlmsg_rt.SetRouteMessage (rtmsg);
-      nlmsg_dump.AppendMessage (nlmsg_rt);
-    }
-
-  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
-  // We only care about staticRouting for netlink support
-  Ipv6StaticRoutingHelper routingHelper6;
-  Ptr<Ipv6StaticRouting> ipv6Static = routingHelper6.GetStaticRouting (ipv6);
-  for (uint32_t i = 0; i < ipv6Static->GetNRoutes (); i ++)
-    {
-      NetlinkMessage nlmsg_rt;
-      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, NETLINK_MSG_F_MULTI, seq, pid);
-      RouteMessage rtmsg;
-      Ipv6RoutingTableEntry route = ipv6Static->GetRoute (i);
-
-      rtmsg.SetFamily (AF_INET6);
-      rtmsg.SetDstLength (128);
-      rtmsg.SetSrcLength (0);
-      rtmsg.SetTos (0);//not clear
-      rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
-      rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
-      rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
-      rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
-
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
-      //ns3 use local address as the route src address
-      // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, 
-      //                                          ipv6->GetSourceAddress(route.GetDest ())));
-      // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, 
-      //                                          ipv6->GetSourceAddress(route.GetDest ())));
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface()));
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface()));      
-      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway()));
-
-      nlmsg_rt.SetHeader (nhr);
-      nlmsg_rt.SetRouteMessage (rtmsg);
-      nlmsg_dump.AppendMessage (nlmsg_rt);
-    }
-
-  return nlmsg_dump;
-}
-
-int32_t
-NetlinkSocket::DoInterfaceAddressMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << type << family);
-  NS_ASSERT (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR);
-
-  // XXX
-  NS_ASSERT_MSG (false, "Not implemented yet (RTM_NEWADDR/RTM_DELADDR)");
-
-  InterfaceAddressMessage ifamsg = nlmsg.GetInterfaceAddressMessage ();
-  Ipv4Address addri, addr_local, bcast;
-  NetlinkAttribute attr_local;
-  uint32_t index = ifamsg.GetInterfaceIndex ();
-  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
-  int flag4 = 0, flag6 = 0;
-
-  if (type == NETLINK_RTM_NEWADDR)
-    {
-      //when adding an interface address, it should check the input arguments
-      //prefix-len and local address attribute
-      if (ifamsg.GetLength () > 32 || 
-          ifamsg.GetAttributeByType (attr_local, InterfaceAddressMessage::IF_A_LOCAL) == false)
-        {
-          m_errno = ERROR_INVAL;
-          return -1;
-        }
-    }  
-
-  //get necessary information for add/del, many attributes we not used
-  for (uint32_t i = 0; i < ifamsg.GetNNetlinkAttribute (); i ++)
-    {
-      NetlinkAttribute attr = ifamsg.GetNetlinkAttribute (i);
-      uint32_t attr_type = attr.GetAttrType ();
-
-      switch(attr_type)
-        {
-        case InterfaceAddressMessage::IF_A_ADDRESS:
-          addri = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
-          break;
-        case InterfaceAddressMessage::IF_A_BROADCAST:
-          bcast = Ipv4Address::ConvertFrom(attr.GetAttrPayload ().GetAddress ());
-          break;
-        case InterfaceAddressMessage::IF_A_LOCAL:
-          addr_local = Ipv4Address::ConvertFrom(attr.GetAttrPayload ().GetAddress ());
-          break;
-        case InterfaceAddressMessage::IF_A_LABEL:
-        case InterfaceAddressMessage::IF_A_ANYCAST:
-          break;
-        }
-    }
-
-  if (type == NETLINK_RTM_NEWADDR)
-    {
-      //when adding an interface address by index, if the indexed interface was not exist,
-      //create an new NetDevice with an new index and set the address
-      //otherwise set the indexed interface directly
-      if (index >= ipv4->GetNInterfaces ())
-        {          
-          Ptr<SimpleNetDevice> dev;
-          dev = CreateObject<SimpleNetDevice> ();
-          dev ->SetAddress (Mac48Address::Allocate ());
-          m_node->AddDevice (dev);
-
-          uint32_t netdev_idx = ipv4->AddInterface (dev);
-          // FIXME!
-          Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (addri, Ipv4Mask ());
-          ipv4->AddAddress (netdev_idx, ipv4Addr);
-          ipv4->SetUp (netdev_idx);
-          NS_LOG_INFO ("Add an interface address at index "<< netdev_idx << "but not the ifamsg input" << index);
-        }
-      else
-        {
-          Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (addri, Ipv4Mask ());
-          ipv4->AddAddress (index, ipv4Addr);
-          if (!ipv4->IsUp (index))
-            ipv4->SetUp (index);
-        }    
-      flag4 = 1;
-    }
-  else//type == NETLINK_RTM_DELADDR
-    {
-      //when delete an interface address by index, if the indexed interface  was not exist
-      //return an error EINVAL, otherwise set down the interface which has the addri
-      if (index >= ipv4->GetNInterfaces ())
-        {
-          m_errno = ERROR_NODEV;
-          return -1;
-        }
-      else
-        {
-          for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i ++)
-            {
-              Ipv4Address ad = ipv4->GetAddress (i, 0).GetLocal ();
-              if (ad == addri && ipv4->IsUp (i))
-                {
-                  ipv4->SetDown (i);
-                  break;
-                }
-              if (i == ipv4->GetNInterfaces () - 1)
-                {
-                  m_errno = ERROR_ADDRNOTAVAIL;
-                  return -1;
-                }
-            }
-          flag4 = 1;
-        }      
-    }
-  
-  //then send an broadcast message, let all user know this operation happened
-  NetlinkMessage nlmsg_broadcast = nlmsg;
-  NetlinkMessageHeader nhr;
-  nhr.SetMsgLen (nlmsg.GetHeader ().GetMsgLen ());
-  nhr.SetMsgType (nlmsg.GetHeader ().GetMsgType ());
-  nlmsg_broadcast.SetHeader (nhr);
-  if (flag4)
-    {
-      SendMessageBroadcast (nlmsg_broadcast, 0, NETLINK_RTM_GRP_IPV4_IFADDR, GetNode ());
-    }
-  else if (flag6)
-    {
-      SendMessageBroadcast (nlmsg_broadcast, 0, RTMGRP_IPV6_IFADDR, GetNode ());
-    }
-
-  return 0;
-}
-
-int32_t
-NetlinkSocket::DoInterfaceInfoMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << type << family);
-  NS_ASSERT (type == NETLINK_RTM_GETLINK || type == NETLINK_RTM_SETLINK);
-  InterfaceInfoMessage ifinfomsg = nlmsg.GetInterfaceInfoMessage ();
-  // XXX
-  NS_ASSERT_MSG (false, "Not implemented yet (RTM_GETLINK/RTM_SETLINK)");
-  return -1;
-}
-
-Address
-NetlinkSocket::ConvertFrom (uint8_t family, const Address &address)
-{
-  Address retval;
-  if (family == AF_INET)
-    {
-      retval = Ipv4Address::ConvertFrom (address);
-    }
-  else if (family == AF_INET6)
-    {
-      retval = Ipv6Address::ConvertFrom (address);
-    }
-  return retval;
-}
-
-int32_t
-NetlinkSocket::DoRouteMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
-{
-  NS_LOG_FUNCTION (this << type << family);
-  NS_ASSERT (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE ||type == NETLINK_RTM_GETROUTE);
-
-  RouteMessage rtmsg = nlmsg.GetRouteMessage ();
-  Ipv4Address src, dest, gateway;
-  Ipv6Address src6, dest6, gateway6;
-  uint32_t index = 0;
-  int attr_flags[RouteMessage::RT_A_MAX] = {0};
-  uint8_t dstlen = rtmsg.GetDstLength ();
-
-  //get necessary information for add/del, many attributes we not used
-  for (uint32_t i = 0; i < rtmsg.GetNNetlinkAttribute (); i ++)
-    {
-      NetlinkAttribute attr = rtmsg.GetNetlinkAttribute (i);
-      uint32_t attr_type = attr.GetAttrType ();
-      attr_flags[attr_type] = 1;
-
-      switch(attr_type)
-        {
-        case RouteMessage::RT_A_DST:
-          if (family == AF_INET)
-            {
-              dest = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
-            }
-          else if (family == AF_INET6)
-            {
-              dest6 = Ipv6Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
-            }
-          break;
-        case RouteMessage::RT_A_SRC:
-          if (family == AF_INET)
-            {
-              src = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
-            }
-          else if (family == AF_INET6)
-            {
-              src6 = Ipv6Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
-            }
-          break;
-        case RouteMessage::RT_A_OIF:
-          index = attr.GetAttrPayload ().GetU32 ();
-          break;
-        case RouteMessage::RT_A_GATEWAY:
-          if (family == AF_INET)
-            {
-              gateway = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
-            }
-          else if (family == AF_INET6)
-            {
-              gateway6 = Ipv6Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
-            }
-          break;
-        case RouteMessage::RT_A_IIF:
-        case RouteMessage::RT_A_PRIORITY:
-        case RouteMessage::RT_A_PREFSRC:
-        case RouteMessage::RT_A_METRICS:
-        case RouteMessage::RT_A_MULTIPATH:
-        case RouteMessage::RT_A_PROTOINFO:
-        case RouteMessage::RT_A_FLOW:
-        case RouteMessage::RT_A_CACHEINFO:
-        case RouteMessage::RT_A_SESSION:
-        case RouteMessage::RT_A_MP_ALGO:
-        case RouteMessage::RT_A_TABLE:
-          NS_LOG_INFO("route attribute not used by ns3" << attr_type);
-          //not used by ns3
-          break;
-        }
-    }
-
-  // Sigh....
-  Ptr<Ipv4>ipv4 = m_node->GetObject<Ipv4> ();
-  Ipv4StaticRoutingHelper routingHelper;
-  Ptr<Ipv4StaticRouting> ipv4Static = routingHelper.GetStaticRouting (ipv4);
-
-  Ptr<Ipv6>ipv6 = m_node->GetObject<Ipv6> ();
-  Ipv6StaticRoutingHelper routingHelper6;
-  Ptr<Ipv6StaticRouting> ipv6Static = routingHelper6.GetStaticRouting (ipv6);
-
-  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Route message, type: " << type << "; from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
-      << " to " << dest<< " through " << gateway);
-
-  if (type == NETLINK_RTM_NEWROUTE)
-    {
-      //ns3 add a route entry only depends on 2 or 3 attribute
-      //other route msg attibute were ignored
-      if (attr_flags[RouteMessage::RT_A_DST])
-        {
-          if (family == AF_INET)
-            {
-              if (!attr_flags[RouteMessage::RT_A_OIF])
-                {
-                  bool found = 0;
-                  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
-                    {
-                      for (uint32_t j = 0; j < ipv4->GetNAddresses (i); j++)
-                        {
-                          if ((attr_flags[RouteMessage::RT_A_GATEWAY]))
-                            {
-                              Ipv4Mask mask = ipv4->GetAddress (i, j).GetMask ();
-                              if (mask.IsMatch (ipv4->GetAddress (i, j).GetLocal (), gateway))
-                                {
-                                  index = i;
-                                  found = true;
-                                  break;
-                                }
-                            }
-                          if (found) break;
-                        }
-                    }
-                  if (!found)
-                    {
-                      NS_LOG_DEBUG ("No suitable interface to add an route entry");
-                      m_errno = ERROR_ADDRNOTAVAIL;
-                      return -1;
-                    }
-                }
-            if (dstlen == 32)
-              {
-                int exist_flag = 0;
-                for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); ++i)
-                  {
-                    Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
-                    if (dest == rt.GetDest ())
-                      {
-                        exist_flag = 1;
-                      }
-                  }
-
-                if (exist_flag)
-                  { //route to dest already exists
-                    int delete_flag = 0;
-                    if (nlmsg.GetHeader ().GetMsgFlags () & NETLINK_MSG_F_REPLACE)
-                      {
-                        for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); ++i)
-                          {
-                            Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
-                            if (dest == rt.GetDest ())
-                              {
-                                ipv4Static->RemoveRoute (i);
-                                NS_LOG_DEBUG ("Route from  " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << " to "
-                                    << dest << " through " << gateway << " removed");
-                                delete_flag = 1;
-                              }
-                          }
-
-                        if (!delete_flag)
-                          {
-                             NS_LOG_INFO ("no route entry removed by dest address in new route sector " << dest);
-                             m_errno = ERROR_INVAL;
-                             return -1;
-                           }
-                      }
-                    else
-                      {
-                        NS_LOG_DEBUG ("Route exists but overwriting declined!");
-                      }
-                    if ((attr_flags[RouteMessage::RT_A_GATEWAY]))
-                      {
-                        NS_LOG_DEBUG (Simulator::Now().GetSeconds() << "Overwrite route from "
-                            << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << " to " << dest<< " through " << gateway << " with index" << index);
-                        ipv4Static->AddHostRouteTo (dest, gateway, index);
-                      }
-                    else
-                      {
-                        NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Overwrite route from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
-                            << " to " << dest<< " through " << "self" << " with index" << index);
-                        ipv4Static->AddHostRouteTo (dest, index);
-                      }
-                }
-                else
-                  { //route to dest doesn't exist
-                    if (nlmsg.GetHeader ().GetMsgFlags () & NETLINK_MSG_F_CREATE)
-                      {
-                        if (attr_flags[RouteMessage::RT_A_GATEWAY])
-                          {
-                            NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Add new route from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
-                                << " to " << dest<< " through " << gateway << " with index" << index);
-                            ipv4Static->AddHostRouteTo (dest, gateway, index);
-                          }
-                        else
-                          {
-                            NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Add new route from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
-                                << " to " << dest<< " through " << "self" << " with index" << index);
-                            ipv4Static->AddHostRouteTo (dest, index);
-                          }
-                      }
-                    else
-                      {
-                        NS_LOG_ERROR ("Route doesn't exist but writing declined!");
-                      }
-                  }
-
-                NS_LOG_DEBUG ("=After change attempt=");
-                //Dump of table
-                NS_LOG_DEBUG (m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << ":");
-                for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); ++i)
-                  {
-                    Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
-                    NS_LOG_DEBUG (rt.GetDest () << " through " << rt.GetGateway ());
-                  }
-                NS_LOG_DEBUG ("= = = = = = = = = = =");
-              }
-            else // dstlen != 32
-              {
-                if (attr_flags[RouteMessage::RT_A_GATEWAY])
-                  {
-                    ipv4Static->AddNetworkRouteTo (dest, Ipv4Mask (~(1<<(32 - dstlen))+1), gateway, index);
-                  }
-                else
-                  {
-                    ipv4Static->AddNetworkRouteTo (dest, Ipv4Mask (~(1<<(32 - dstlen))+1), index);
-                  }
-              }
-          }
-          else if (family == AF_INET6)
-            {
-            if (!attr_flags[RouteMessage::RT_A_OIF])
-              {
-#ifdef FIXME
-              if (ipv6->GetIfIndexForDestination (gateway6, index) == false)
-                {
-                  NS_LOG_INFO ("No suitable interface to add an route entry");
-                  m_errno = ERROR_ADDRNOTAVAIL;
-                  return -1;
-                }
-#endif
-              }
-
-            Ipv6Prefix pref (dstlen);
-            if (attr_flags[RouteMessage::RT_A_GATEWAY])
-              {
-                ipv6Static->AddNetworkRouteTo (dest6, pref, gateway6, index);
-              }
-            else
-              {
-                ipv6Static->AddNetworkRouteTo (dest6, pref, Ipv6Address("::"), index);
-              }
-            }
-          }
-        else
-          {
-            NS_LOG_INFO("too few attributes to add an route entry");
-            m_errno = ERROR_INVAL;
-            return -1;
-          }
-    }
-  else if (type == NETLINK_RTM_DELROUTE)
-    {
-      NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Route delete request from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
-          << " to " << dest<< " through " << gateway);
-      if (attr_flags[RouteMessage::RT_A_DST])
-        {
-          int delete_flag = 0;
-
-          if (family == AF_INET)
-            {
-              for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); i ++)
-                {
-                Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
-                if (gateway == rt.GetGateway () && dest == rt.GetDest ())
-                  {
-                    ipv4Static->RemoveRoute (i);
-                    delete_flag = 1;
-                  }
-                }
-            }
-          else if (family == AF_INET6)
-            {
-              for (uint32_t i = 0; i < ipv6Static->GetNRoutes (); i ++)
-                {
-                Ipv6RoutingTableEntry rt = ipv6Static->GetRoute (i);
-                if (gateway6 == rt.GetGateway () && dest6 == rt.GetDest ())
-                  {
-                    ipv6Static->RemoveRoute (i);
-                    delete_flag = 1;
-                  }
-                }
-            }
-
-          if (!delete_flag)
-            {
-              NS_LOG_INFO ("no route entry removed by dest address " << dest);
-              m_errno = ERROR_INVAL;
-              return -1;
-            }
-        }
-      else
-        {
-          NS_LOG_INFO ("too few attributes to add an route entry");
-          m_errno = ERROR_INVAL;
-          return -1;    
-        }
-    }
-  else// type == NETLINK_RTM_GETROUTE
-    {
-      NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "GetRoute "<< "from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << " to " << dest);
-      if (!attr_flags[RouteMessage::RT_A_DST])
-        {
-          NS_LOG_INFO ("too few attributes to get an route entry");
-          m_errno = ERROR_INVAL;
-          return -1;
-        }
-      
-      int get_flag = 0;
-      if (family == AF_INET)
-        {
-          for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); i ++)
-            {
-              Ipv4RoutingTableEntry route = ipv4Static->GetRoute (i);
-              //find the route entry with same dest address and send unicast to user space
-              if (dest.IsEqual (route.GetDest ()))
-                {
-                  //                Ptr<Ipv4>ipv4 = m_node->GetObject<Ipv4> ();
-                  NetlinkMessage nlmsg_route;
-                  NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, 0, 
-                                                                   nlmsg.GetHeader ().GetMsgSeq (), m_srcPid);
-                  RouteMessage rtmsg;
-
-                  //fill rtmsg and attributes
-                  rtmsg.SetFamily (AF_INET);
-                  rtmsg.SetDstLength (32);
-                  rtmsg.SetSrcLength (0);
-                  rtmsg.SetTos (0);//not clear
-                  rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
-                  rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
-                  rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
-                  rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
-
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
-                  //ns3 use local address as the route src address
-                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, ipv4->GetSourceAddress(route.GetDest ())));
-                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, ipv4->GetSourceAddress(route.GetDest ())));
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface ()));
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface ()));
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway ()));
-
-                  //fill an netlink message body
-                  nlmsg_route.SetHeader (nhr);
-                  nlmsg_route.SetRouteMessage (rtmsg);
-                  
-                  SendMessageUnicast (nlmsg_route, m_srcPid, 1);
-                  get_flag = 1;
-                }
-            }
-        }
-      else if (family == AF_INET6)
-        {
-          for (uint32_t i = 0; i < ipv6Static->GetNRoutes(); i ++)
-            {
-              Ipv6RoutingTableEntry route = ipv6Static->GetRoute (i);
-              //find the route entry with same dest address and send unicast to user space
-              if (dest6.IsEqual (route.GetDest ()))
-                {
-                  NetlinkMessage nlmsg_route;
-                  NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, 0, 
-                                                                   nlmsg.GetHeader ().GetMsgSeq (), m_srcPid);
-                  RouteMessage rtmsg;
-
-                  //fill rtmsg and attributes
-                  rtmsg.SetFamily (AF_INET6);
-                  rtmsg.SetDstLength (32);
-                  rtmsg.SetSrcLength (0);
-                  rtmsg.SetTos (0);//not clear
-                  rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
-                  rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
-                  rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
-                  rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
-
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
-                  //ns3 use local address as the route src address
-                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, ipv6->GetSourceAddress(route.GetDest ())));
-                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, ipv6->GetSourceAddress(route.GetDest ())));
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface ()));
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface ()));
-                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway ()));
-
-                  //fill an netlink message body
-                  nlmsg_route.SetHeader (nhr);
-                  nlmsg_route.SetRouteMessage (rtmsg);
-
-                  SendMessageUnicast (nlmsg_route, m_srcPid, 1);
-                  get_flag = 1;
-                }
-            }
-        }
-      
-      if (!get_flag)
-        {
-          NS_LOG_INFO ("no route entry exist by dest address" << dest);
-          m_errno = ERROR_INVAL;
-          return -1;
-        }
-    }
-
-  //then send an broadcast message, let all user know this operation happened
-  MultipartNetlinkMessage nlmsg_multi;
-  NetlinkMessage nlmsg_broadcast = nlmsg;
-  NetlinkMessage nlmsg_done;
-  NetlinkMessageHeader nhr_done = NetlinkMessageHeader (NETLINK_MSG_DONE, NETLINK_MSG_F_MULTI, 0, 0);
-  nlmsg_done.SetHeader (nhr_done);
-  nlmsg_multi.AppendMessage (nlmsg);
-  nlmsg_multi.AppendMessage (nlmsg_done);
-  SendMessageBroadcast (nlmsg_multi, 0, NETLINK_RTM_GRP_IPV4_ROUTE, GetNode ());
-  //   SendMessageBroadcast(nlmsg_broadcast, 0, RTMGRP_IPV6_ROUTE);
-  return 0;
-}
-
-int32_t
-NetlinkSocket::NotifyIfLinkMessage (Address address, uint16_t type, uint8_t family)
-{
-  NS_ASSERT_MSG (false, "Not implemented yet (NotifyIfLinkMessage)");
-  return 0;
-}
-
-int32_t
-NetlinkSocket::NotifyIfAddrMessage (Ipv6Interface* interface, Ipv6Address addr, int cmd)
-{
-  MultipartNetlinkMessage nlmsg_multi;
-  NetlinkMessage nlmsg_ifa;
-  NetlinkMessageHeader nhr = NetlinkMessageHeader (cmd, NETLINK_MSG_F_MULTI, 0, 0);
-  InterfaceAddressMessage ifamsg;
-
-  NS_ASSERT_MSG (false, "Not implemented yet (NotifyIfAddrMessage)");
-
-  // FIXME!
-  Ipv6Prefix prefix = Ipv6Prefix(64);
-
-  //here get the address mask length
-  uint8_t bytes[16];
-  prefix.GetBytes (bytes);
-  uint8_t mask_len = 0;
-  for (int j = 0; j < 16; j++)
-    {
-      while (bytes[j])
-        {
-          bytes[j] = bytes[j] << 1;
-          mask_len ++;
-        }
-    }
-      
-  ifamsg.SetInterfaceIndex (interface->GetDevice ()->GetIfIndex ());
-  ifamsg.SetFamily (AF_INET6);
-  ifamsg.SetLength (mask_len);
-  ifamsg.SetFlags (0);
-  ifamsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
-
-  ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LOCAL,    ADDRESS, addr));
-  ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ADDRESS,  ADDRESS, addr));
-  //  ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_BROADCAST,ADDRESS, bcast));
-  //      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LABEL,    STRING,  "ns3-ifaddr"));//not used in ns3
-  //ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ANYCAST,  ADDRESS, Ipv4Address("0.0.0.0")));//not used in ns3
-  //XXXother attributes not used by ns3
-
-  nlmsg_ifa.SetHeader (nhr);
-  nlmsg_ifa.SetInterfaceAddressMessage (ifamsg);
-
-  NetlinkMessage nlmsg_done;
-  NetlinkMessageHeader nhr_done = NetlinkMessageHeader (NETLINK_MSG_DONE, NETLINK_MSG_F_MULTI, 0, 0);
-  nlmsg_done.SetHeader (nhr_done);
-
-  nlmsg_multi.AppendMessage (nlmsg_ifa);
-  nlmsg_multi.AppendMessage (nlmsg_done);
-
-  SendMessageBroadcast (nlmsg_multi, 0, RTMGRP_IPV6_IFADDR, interface->GetDevice ()->GetNode ());  
-  return 0;
-}
-
-#ifdef FIXME
-int32_t
-NetlinkSocket::NotifyRouteMessage(Ojbect route, uint16_t type, uint8_t family)
-{
-  NetlinkMessage nlmsg_broadcast = nlmsg;
-  NetlinkMessageHeader nhr;
-  NS_ASSERT_MSG (false, "Not implemented yet");
-
-  nhr.SetMsgLen (nlmsg.GetHeader ().GetMsgLen ());
-  nhr.SetMsgType (nlmsg.GetHeader ().GetMsgType ());
-  nlmsg_broadcast.SetHeader (nhr);
-  SendMessageBroadcast (nlmsg_broadcast, 0, RTMGRP_IPV6_ROUTE);
-  return 0;
-}
-#endif
-
-}//namespace ns3
--- a/model/netlink-socket.h	Tue Apr 19 23:13:50 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 Liu Jian
- *
- * 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: Liu Jian <liujatp@gmail.com>
- *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
- */
-#ifndef NETLINK_SOCKET_H
-#define NETLINK_SOCKET_H
-
-#include <stdint.h>
-#include <queue>
-#include "netlink-message.h"
-#include "ns3/callback.h"
-#include "ns3/ptr.h"
-#include "ns3/traced-callback.h"
-#include "ns3/socket.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv6-address.h"
-#include "ns3/ipv6-interface.h"
-
-namespace ns3 {
-
-class Node;
-class Packet;
-class NetlinkSocketAddress;
-
-/**
-* \brief A NetlinkSocket is  used  to transfer information 
-between kernel and userspace processes .
-*
-* here we focus on NETLINK_ROUTE: Receives routing and link
-* updates and may be used to modify  the  routing  tables 
-* (both IPv4 and IPv6), IP addresses, link parame- ters, neighbor
-* setups, queueing disciplines, traffic classes and packet 
-* classifiers (see rtnetlink (7)). This socket type is very similar
-* to the linux and BSD "packet" sockets.
-*
-* Here is a summary of the semantics of this class:
-* - Bind: Bind uses only the protocol and device fields of the 
-*       NetlinkSocketAddress.
-*
-* - Send: send the input packet to the underlying kernel space
-*       with its own address. The socket must  be bound.
-*
-* - Recv: receive packet from the kernel space.
-*
-* - Accept: not allowed
-* - Connect: not allowed
-*/
-class NetlinkSocket : public Socket
-{
-public:
-  static TypeId GetTypeId (void);
-
-  NetlinkSocket ();
-  virtual ~NetlinkSocket ();
-
-  void SetNode (Ptr<Node> node);
-
-  virtual enum SocketErrno GetErrno (void) const;
-  virtual enum Socket::SocketType GetSocketType (void) const;
-  virtual Ptr<Node> GetNode (void) const;
-  virtual int Bind (void);
-  virtual int Bind (const Address & address);
-  virtual int Close (void);
-  virtual int ShutdownSend (void);
-  virtual int ShutdownRecv (void);
-  virtual int Connect (const Address &address);
-  virtual int Listen (void);
-  virtual uint32_t GetTxAvailable (void) const;
-  virtual int Send (Ptr<Packet> p, uint32_t flags);
-  virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
-  virtual uint32_t GetRxAvailable (void) const;
-  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
-  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags, 
-                                Address &fromAddress);
-  virtual int GetSockName (Address &address) const; 
-  virtual int GetPeerName (Address &address) const;
-  virtual bool SetAllowBroadcast (bool allowBroadcast);
-  virtual bool GetAllowBroadcast () const;
-
-  uint32_t GetSrcPid (void) const;
-  uint32_t GetSrcGroups (void)const;
-  uint32_t GetDstPid (void) const;
-  uint32_t GetDstGroups (void)const;
-  int32_t NotifyIfAddrMessage (Ipv6Interface* interface, Ipv6Address addr, int cmd);
-  int32_t NotifyIfLinkMessage (Address address, uint16_t type, uint8_t family);
-  //  int32_t NotifyRouteMessage(Ojbect route, uint16_t type, uint8_t family);
-
-private:
-  int DoBind (const NetlinkSocketAddress &address);
-  virtual void DoDispose (void);
-  void ForwardUp (Ptr<Packet> p, NetlinkSocketAddress &address);
-
-
-
-  /**
- * the functions below were for kernel parsing netlink message,set private here
- * when netlink msg sent to kernel through netlink socket, it was parsed in kernel
- * space, then, kernel add/del its route/interface/link table or dump all information
- * to user space
- */
-
-  int32_t HandleMessage (const NetlinkMessage &nlmsg);
-  /**
-  * when kernel find the message truncated or user need an ACK response,
-  * it send ACK back to user space, with the error code(0 for ACK, > 0 for error).
-  */
-  void SendAckMessage (const NetlinkMessage &nlmsg, int32_t errorcode);
-
-  /**
-  * \brief unicast an message to user
-  * \param nlmsg the netlink message to transmit
-  * \param pid the netlink pid of destination socket
-  * \param nonbloack always true
-  */
-  int32_t SendMessageUnicast (const MultipartNetlinkMessage &nlmsg, 
-                              uint32_t pid, int32_t nonblock);
-  /**
-  * \brief spread message to netlink group user
-  * \param nlmsg the netlink message to transmit
-  * \param pid the netlink pid of the kernel, always 0
-  * \param group multicast group id
-  */
-  static int32_t SendMessageBroadcast (const MultipartNetlinkMessage &nlmsg, 
-                                       uint32_t pid, uint32_t group, Ptr<Node> node);
-
-  /**
-  * these functions below are for NETLINK_ROUTE protocol, it handle the netlink 
-  * message like linux kernel work.  this implementation follows the kernel code 
-  * linux/rtnetlink.c, focus on "interface address, interface info and route entry",
-  * now we will only simply support three types operations of  NETLINK_ROUTE 
-  * protocol
-  */
-  
-  /**
-  * \returns 0 if messge not processed, < 0 for success or an error.
-  * this function would call dumping/doing functions to  
-  */
-  int32_t HandleNetlinkRouteMessage (const NetlinkMessage &nlmsg);
-  
-  /**
-  * \returns 0 if dumping operation is OK, < 0 for an error.
-  */ 
-  int32_t DumpNetlinkRouteMessage (const NetlinkMessage &nlmsg, 
-                                   uint16_t type, uint8_t family);
-  MultipartNetlinkMessage BuildInterfaceAddressDumpMessage (uint32_t pid,
-                                                            uint32_t seq, uint8_t family);
-  MultipartNetlinkMessage BuildInterfaceInfoDumpMessage (uint32_t pid,
-                                                         uint32_t seq, uint8_t family);
-  MultipartNetlinkMessage BuildRouteDumpMessage (uint32_t pid,
-                                                 uint32_t seq, uint8_t family);
-
-  /**
-  * \returns 0 if doing operation(ADD/DEL/GET) is OK, < 0 for an error.
-  */
-  int32_t DoNetlinkRouteMessage (const NetlinkMessage &nlmsg,
-                                 uint16_t type, uint8_t family);
-  int32_t DoInterfaceAddressMessage (const NetlinkMessage &nlmsg, 
-                                     uint16_t type, uint8_t family);
-  int32_t DoInterfaceInfoMessage (const NetlinkMessage &nlmsg, 
-                                  uint16_t type, uint8_t family);
-  int32_t DoRouteMessage (const NetlinkMessage &nlmsg, 
-                          uint16_t type, uint8_t family);
-
-  int ErrnoToSimuErrno (void);
-  Address ConvertFrom (uint8_t family, const Address &address);
-
-  Ptr<Node> m_node;
-  enum SocketErrno m_errno;
-  bool m_shutdownSend;
-  bool m_shutdownRecv;
-
-  std::queue<Ptr<Packet> > m_dataReceiveQueue;
-  uint32_t m_rxAvailable;
-  TracedCallback<Ptr<const Packet> > m_dropTrace;
-  // Socket options (attributes)
-  uint32_t m_rcvBufSize;
-
-  uint32_t m_srcPid;
-  uint32_t m_srcGroups;
-  uint32_t m_dstPid;
-  uint32_t m_dstGroups;
-  Callback<void, Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
-};
-
-}//namespace ns3
-
-#endif /* NETLINK_SOCKET_H */
-
-
--- a/model/ns3-socket-fd-factory.cc	Tue Apr 19 23:13:50 2011 +0200
+++ b/model/ns3-socket-fd-factory.cc	Thu May 05 09:28:21 2011 +0200
@@ -3,7 +3,7 @@
 #include "unix-socket-fd.h"
 #include "unix-datagram-socket-fd.h"
 #include "unix-stream-socket-fd.h"
-#include "netlink-socket-factory.h"
+#include "ns3/netlink-socket-factory.h"
 #include "ns3/socket-factory.h"
 #include "ns3/socket.h"
 #include "ns3/uinteger.h"
@@ -29,36 +29,52 @@
 UnixFd *
 Ns3SocketFdFactory::CreateSocket (int domain, int type, int protocol)
 {
-  NS_ASSERT (domain == PF_INET || domain == PF_NETLINK || domain == PF_INET6);
-
   UnixSocketFd *socket = 0;
   Ptr<Socket> sock;
 
-  switch (type) {
-  case SOCK_DGRAM: {
-    TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
-    Ptr<SocketFactory> factory = GetObject<SocketFactory> (tid);
-    sock = factory->CreateSocket ();
-    socket = new UnixDatagramSocketFd (sock);
-  } break;
-  case SOCK_RAW: {
-    TypeId tid = TypeId::LookupByName ("ns3::Ipv4RawSocketFactory");
-    Ptr<SocketFactory> factory = GetObject<SocketFactory> (tid);
-    sock = factory->CreateSocket ();
-    sock->SetAttribute ("Protocol", UintegerValue (protocol));
-    socket = new UnixDatagramSocketFd (sock);
-  } break;
-  case SOCK_STREAM: {
-    TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory");
-    Ptr<SocketFactory> factory = GetObject<SocketFactory> (tid);
-    sock = factory->CreateSocket ();
-    socket = new UnixStreamSocketFd (sock);
-  } break;
-    default:
-      // XXX insert netlink creation here.
-      NS_FATAL_ERROR ("missing socket type");
-      break;
-  }
+  if (domain == PF_INET)
+    {
+      switch (type) {
+      case SOCK_DGRAM: {
+	TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+	Ptr<SocketFactory> factory = GetObject<SocketFactory> (tid);
+	sock = factory->CreateSocket ();
+	socket = new UnixDatagramSocketFd (sock);
+      } break;
+      case SOCK_RAW: {
+	TypeId tid = TypeId::LookupByName ("ns3::Ipv4RawSocketFactory");
+	Ptr<SocketFactory> factory = GetObject<SocketFactory> (tid);
+	sock = factory->CreateSocket ();
+	sock->SetAttribute ("Protocol", UintegerValue (protocol));
+	socket = new UnixDatagramSocketFd (sock);
+      } break;
+      case SOCK_STREAM: {
+	TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory");
+	Ptr<SocketFactory> factory = GetObject<SocketFactory> (tid);
+	sock = factory->CreateSocket ();
+	socket = new UnixStreamSocketFd (sock);
+      } break;
+      default:
+	NS_FATAL_ERROR ("missing socket type");
+	break;
+      }
+    }
+  else if (domain == PF_NETLINK)
+    {
+      switch (type) {
+      case SOCK_DGRAM: {
+	sock = m_netlink->CreateSocket ();
+	socket = new UnixDatagramSocketFd (sock);
+      } break;
+      default:
+	NS_FATAL_ERROR ("missing socket type");
+	break;
+      }
+    }
+  else
+    {
+      NS_FATAL_ERROR ("unsupported domain");
+    }
 
   return socket;
 }
--- a/model/ns3-socket-fd-factory.h	Tue Apr 19 23:13:50 2011 +0200
+++ b/model/ns3-socket-fd-factory.h	Thu May 05 09:28:21 2011 +0200
@@ -5,7 +5,7 @@
 
 namespace ns3 {
 
-class NetlinkSocketFactory;
+class SocketFactory;
 
 class Ns3SocketFdFactory : public SocketFdFactory
 {
@@ -14,7 +14,7 @@
   Ns3SocketFdFactory ();
   virtual UnixFd *CreateSocket (int domain, int type, int protocol);
  private:
-  Ptr<NetlinkSocketFactory> m_netlink;
+  Ptr<SocketFactory> m_netlink;
 };
 
 } // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-attribute.cc	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,433 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#include "netlink-attribute.h"
+#include "netlink-message.h"
+#include "netlink-message-route.h"
+#include "ns3/address-utils.h"
+
+namespace ns3 {
+
+
+/***********************************************************************************
+* \ NetlinkAttributeValue
+***********************************************************************************/
+NetlinkAttributeValue::NetlinkAttributeValue ()
+{
+  m_type = UNSPEC;
+  m_u32 = 0;
+}
+
+NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint8_t v)
+{
+  NS_ASSERT (type == U8);
+  m_type = U8;
+  m_u8 = v;
+}
+NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint16_t v)
+{
+  NS_ASSERT (type == U16);
+  m_type = U16;
+  m_u16 = v;
+}
+NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint32_t v)
+{
+  NS_ASSERT (type == U32);
+  m_type = U32;
+  m_u32 = v;
+}
+NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, uint64_t v)
+{
+  NS_ASSERT (type == U64);
+  m_type = U64;
+  m_u64 = v;
+}
+NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, std::string v)
+{
+  NS_ASSERT (type == STRING);
+  m_type = STRING;
+  m_string = v;
+}
+NetlinkAttributeValue:: NetlinkAttributeValue (NetlinkAttributeValueType type, Address v)
+{
+  NS_ASSERT (type == ADDRESS);
+  m_type = ADDRESS;
+  m_address = v;
+}
+
+void
+NetlinkAttributeValue::SetType (NetlinkAttributeValueType type)
+{
+  m_type = type;
+}
+NetlinkAttributeValueType
+NetlinkAttributeValue::GetType (void) const
+{
+  return m_type;
+}
+void
+NetlinkAttributeValue::SetAddress (Address value)
+{
+  m_address = value;
+}
+void
+NetlinkAttributeValue::SetString (std::string value)
+{
+  m_string = value;
+}
+void
+NetlinkAttributeValue::SetU64 (uint64_t value)
+{
+  m_u64 = value;
+}
+void
+NetlinkAttributeValue::SetU32 (uint32_t value)
+{
+  m_u32 = value;
+}
+void
+NetlinkAttributeValue::SetU16 (uint16_t value)
+{
+  m_u16 = value;
+}
+void
+NetlinkAttributeValue::SetU8 (uint8_t value)
+{
+  m_u8 = value;
+}
+Address
+NetlinkAttributeValue::GetAddress (void) const
+{
+  return m_address;
+}
+std::string
+NetlinkAttributeValue::GetString (void) const
+{
+  return m_string;
+}
+uint64_t
+NetlinkAttributeValue::GetU64 (void) const
+{
+  return m_u64;
+}
+uint32_t
+NetlinkAttributeValue::GetU32 (void) const
+{
+  return m_u32;
+}
+uint16_t
+NetlinkAttributeValue::GetU16 (void) const
+{
+  return m_u16;
+}
+uint8_t
+NetlinkAttributeValue::GetU8 (void) const
+{
+  return m_u8;
+}
+
+void
+NetlinkAttributeValue::Serialize (Buffer::Iterator& start) const
+{
+  uint32_t len;
+
+  if (m_type == U8)
+    {
+      start.WriteU8 (m_u8);
+      len = 1;
+    }
+  else if(m_type == U16)
+    {
+      start.WriteU16 (m_u16);
+      len = 2;
+    }
+  else if(m_type == U32)
+    {
+      start.WriteU32 (m_u32);
+      len = 4;
+    }
+  else if(m_type == STRING)
+    {
+      start.Write ((const uint8_t *)m_string.c_str (), (uint32_t)m_string.size ()+1);
+      len = (uint32_t)m_string.size () + 1;
+    }
+  else if(m_type == ADDRESS)
+    {
+      WriteTo (start, m_address);
+      len = m_address.GetLength ();
+    }
+  else
+    {
+      len = 0;
+    }
+  //netlink align
+  start.WriteU8 (0, NETLINK_MSG_ALIGN (len) - len);
+}
+
+uint32_t
+NetlinkAttributeValue::DeserializeWithType (Buffer::Iterator& start, 
+                                            NetlinkAttributeValueType_e type, uint16_t remaining)
+{
+  uint32_t len =0;
+  m_type = type;  
+
+  if (m_type == U8)
+    {
+      m_u8 = start.ReadU8 ();
+      len = 1;
+    }
+  else if (m_type == U16)
+    {
+      m_u16 = start.ReadU16 ();
+      len = 2;
+    }
+  else if (m_type == U32)
+    {
+      m_u32 = start.ReadU32 ();
+      len = 4;
+    }
+  else if (m_type == U64)
+    {
+      m_u64 = start.ReadU64 ();
+    }  
+  else if (m_type == STRING)
+    {
+      char buf[512];
+      uint32_t i = 0;
+      do 
+      {
+        buf[i] = start.ReadU8 ();
+      } while (buf[i++]);
+      
+      m_string = std::string (buf);
+      len = (uint32_t)m_string.size () + 1;
+    }
+  else if (m_type == ADDRESS)
+    {
+      ReadFrom (start, m_address, remaining);
+      len = m_address.GetLength ();
+    }
+  else
+    {
+      len = 0;
+    }
+
+  //netlink align
+  uint8_t buf[4];
+  start.Read (buf, NETLINK_MSG_ALIGN (len) - len);
+  
+  return NETLINK_MSG_ALIGN (len);
+}
+
+uint32_t
+NetlinkAttributeValue::GetSerializedSize ()const
+{
+  return NETLINK_MSG_ALIGN (GetSize ());
+}
+
+uint32_t
+NetlinkAttributeValue::GetSize () const
+{
+  uint32_t len;
+
+  if (m_type == U8)
+    {
+      len = 1;
+    }
+  else if(m_type == U16)
+    {
+      len =  2;
+    }
+  else if(m_type == U32)
+    {
+      len =  4;
+    }
+  else if (m_type == STRING)
+    {
+      len =  uint32_t (m_string.size () + 1);
+    }
+  else if (m_type == ADDRESS)
+    {
+      len =  m_address.GetLength ();
+    }
+  else
+    {
+      len = 0;
+    }
+
+    return len;
+}
+
+void
+NetlinkAttributeValue::Print (std::ostream &os) const
+{
+  os << "NetlinkAttributeValue (type= " << m_type <<", v= ";
+  if (m_type == U8)
+    {
+      os << m_u8;
+    }
+  else if (m_type == U16)
+    {
+      os << m_u16;
+    }
+  else if (m_type == U32)
+    {
+      os << m_u32;
+    }
+  else if (m_type == U64)
+    {
+      os << m_u64;
+    }  
+  else if (m_type == STRING)
+    {
+      os << m_string;
+    }
+  else if (m_type == ADDRESS)
+    {
+      os << "address(" << m_address <<")";
+    }
+  else
+    {
+      os << "NULL";
+    }
+  os <<")";
+}
+
+
+/***********************************************************************************
+* \ NetlinkAttribute
+***********************************************************************************/
+
+NetlinkAttribute::NetlinkAttribute ()
+  : m_len(4),
+    m_type (0)
+{
+}
+
+NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint8_t payload)
+{
+  m_payload = NetlinkAttributeValue (payloadtype, payload);
+  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
+  m_type = type;
+}
+
+NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint16_t payload)
+{
+  m_payload = NetlinkAttributeValue (payloadtype, payload);
+  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
+  m_type = type;
+}
+NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint32_t payload)
+{
+  m_payload = NetlinkAttributeValue (payloadtype, payload);
+  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
+  m_type = type;;
+}
+NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint64_t payload)
+{
+  m_payload = NetlinkAttributeValue (payloadtype, payload);
+  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
+  m_type = type;
+}
+NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  std::string payload)
+{
+  m_payload = NetlinkAttributeValue (payloadtype, payload);
+  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
+  m_type = type;
+}
+NetlinkAttribute::NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  Address payload)
+{
+  m_payload = NetlinkAttributeValue (payloadtype, payload);
+  m_len = NETLINK_MSG_ATTR_SIZE + m_payload.GetSize ();
+  m_type = type;
+}
+
+void
+NetlinkAttribute::SetAttrLen (uint16_t v)
+{
+  m_len = v;
+}
+void 
+NetlinkAttribute::SetAttrType (uint16_t v)
+{
+  m_type = v;
+}
+void
+NetlinkAttribute::SetAttrPayload (NetlinkAttributeValue v)
+{
+  m_payload = v;
+}
+uint16_t
+NetlinkAttribute::GetAttrLen () const
+{
+  return m_len;
+}
+uint16_t
+NetlinkAttribute::GetAttrType () const
+{
+  return m_type;
+}
+NetlinkAttributeValue
+NetlinkAttribute::GetAttrPayload() const
+{
+  return m_payload;
+}
+
+void 
+NetlinkAttribute::Print (std::ostream &os) const
+{  
+  os << "NetlinkAttribute "
+     << "len: " << m_len << " "
+     << "type: " << m_type<<" "
+     << "payload:[";
+  m_payload.Print(os);
+  os<<"]";
+}
+
+uint32_t 
+NetlinkAttribute::GetSerializedSize (void) const
+{
+  /* this is the size of an nlattr payload. */
+  return NETLINK_MSG_ATTR_SIZE + m_payload.GetSerializedSize ();
+}
+
+void
+NetlinkAttribute::Serialize (Buffer::Iterator& start) const
+{
+  start.WriteU16 (m_len);
+  start.WriteU16 (m_type);
+  m_payload.Serialize (start);
+}
+
+uint32_t
+NetlinkAttribute::Deserialize (Buffer::Iterator& start, NetlinkAttributeValueType vtypes[])
+{
+  NetlinkAttributeValueType type;
+
+  m_len = start.ReadU16 ();
+  m_type = start.ReadU16 ();
+  type = vtypes[m_type];
+  m_payload.DeserializeWithType (start, type, m_len - 4);
+
+  return GetSerializedSize ();
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-attribute.h	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#ifndef NETLINK_ATTRIBUTE_H
+#define NETLINK_ATTRIBUTE_H
+
+
+#include <stdint.h>
+#include <string>
+#include <ostream>
+#include "ns3/address.h"
+#include "ns3/buffer.h"
+
+namespace ns3 {
+
+/**
+* \brief The Netlink Attribute
+*/
+
+typedef enum NetlinkAttributeValueType_e {
+  UNSPEC, // invalid initial value.
+  U8,
+  U16,
+  U32,
+  U64,
+  STRING,
+  ADDRESS,
+}NetlinkAttributeValueType;
+
+class NetlinkAttributeValue
+{
+public:
+  NetlinkAttributeValue ();
+  NetlinkAttributeValue (NetlinkAttributeValueType type, uint8_t v);
+  NetlinkAttributeValue (NetlinkAttributeValueType type, uint16_t v);
+  NetlinkAttributeValue (NetlinkAttributeValueType type, uint32_t v);
+  NetlinkAttributeValue (NetlinkAttributeValueType type, uint64_t v);
+  NetlinkAttributeValue (NetlinkAttributeValueType type, std::string v);
+  NetlinkAttributeValue (NetlinkAttributeValueType type, Address v);
+  
+  void Serialize (Buffer::Iterator& start) const;
+  uint32_t DeserializeWithType (Buffer::Iterator& start, NetlinkAttributeValueType type, uint16_t remaining);
+  uint32_t GetSerializedSize (void) const;
+  uint32_t GetSize (void) const;
+  void Print (std::ostream &os) const;
+
+  void SetType (NetlinkAttributeValueType type);
+  NetlinkAttributeValueType GetType (void) const;
+  void SetAddress (Address value);
+  void SetString (std::string value);
+  void SetU64 (uint64_t value);
+  void SetU32 (uint32_t value);
+  void SetU16 (uint16_t value);
+  void SetU8 (uint8_t value);
+  Address GetAddress (void) const;
+  std::string GetString (void) const;
+  uint64_t GetU64 (void) const;
+  uint32_t GetU32 (void) const;
+  uint16_t GetU16 (void) const;
+  uint8_t GetU8 (void) const;
+
+private:
+  NetlinkAttributeValueType m_type;
+  uint64_t m_u64;
+  uint32_t m_u32;
+  uint16_t m_u16;
+  uint8_t m_u8;
+  std::string m_string;
+  Address m_address;
+};
+
+struct NetlinkAttribute
+{
+public:
+  NetlinkAttribute ();
+  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint8_t payload);
+  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint16_t payload);
+  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint32_t payload);
+  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  uint64_t payload);
+  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  std::string payload);
+  NetlinkAttribute (uint16_t type, NetlinkAttributeValueType payloadtype,  Address payload);
+
+  //static TypeId GetTypeId (void);
+  //virtual TypeId GetInstanceTypeId (void) const;
+  void Print (std::ostream &os) const;
+  uint32_t GetSerializedSize (void) const;
+  void Serialize (Buffer::Iterator& start) const;
+  uint32_t Deserialize (Buffer::Iterator& start, NetlinkAttributeValueType vtypes[]);
+
+  void SetAttrLen (uint16_t v);
+  void SetAttrType (uint16_t v);
+  void SetAttrPayload (NetlinkAttributeValue v);
+  uint16_t GetAttrLen () const;
+  uint16_t GetAttrType () const;
+  NetlinkAttributeValue GetAttrPayload () const;
+
+private:
+  static const int NETLINK_MSG_ATTR_SIZE = 4; /* size of the nlattr field*/
+  uint16_t m_len;
+  uint16_t m_type; 
+  NetlinkAttributeValue m_payload;
+};
+
+}; // namespace ns3
+
+#endif /* NETLINK_ATTRIBUTE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-message-route.cc	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,647 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#include "netlink-message-route.h"
+#include "netlink-message.h"
+
+namespace ns3 {
+
+/***********************************************************************************
+* \ NetlinkPayload
+***********************************************************************************/
+TypeId 
+NetlinkPayload::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NetlinkPayload")
+    .SetParent<ObjectBase> ()
+    ;
+  return tid;
+}
+
+
+/***********************************************************************************
+* \ GeneralMessage
+***********************************************************************************/
+
+NS_OBJECT_ENSURE_REGISTERED (GeneralMessage);
+NS_OBJECT_ENSURE_REGISTERED (InterfaceInfoMessage);
+NS_OBJECT_ENSURE_REGISTERED (InterfaceAddressMessage);
+NS_OBJECT_ENSURE_REGISTERED (RouteMessage);
+
+GeneralMessage::GeneralMessage ()
+  : m_family(0)
+{}
+GeneralMessage::~GeneralMessage ()
+{}
+
+void
+GeneralMessage::SetFamily (uint8_t v)
+{
+  m_family = v;
+}
+uint8_t
+GeneralMessage::GetFamily (void) const
+{
+  return m_family;
+}
+
+TypeId 
+GeneralMessage::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::GeneralMessage")
+    .SetParent<NetlinkPayload> ()
+    .AddConstructor<GeneralMessage> ()
+    ;
+  return tid;
+}
+
+TypeId 
+GeneralMessage::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+GeneralMessage::Print (std::ostream &os) const
+{
+  os << " ----GeneralMessage ("
+     << "family: " << (uint32_t)m_family << ")"; 
+}
+
+uint32_t 
+GeneralMessage::GetSerializedSize (void) const
+{
+  /* this is the size of an nlmsghdr payload. */
+  return NETLINK_MSG_ALIGN (NETLINK_GENMSG_SIZE);
+}
+
+
+void
+GeneralMessage::Serialize (Buffer::Iterator& start) const
+{
+  start.WriteU8 (m_family);
+  start.WriteU8 (0, 3);
+}
+
+uint32_t
+GeneralMessage::Deserialize (Buffer::Iterator& start)
+{
+  uint8_t buf[3];
+  m_family = start.ReadU8 ();
+  start.Read (buf, 3);
+  return GetSerializedSize ();
+}
+uint32_t
+GeneralMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
+{
+  uint8_t buf[3];
+  m_family = start.ReadU8 ();
+  start.Read (buf, 3);
+  return GetSerializedSize ();
+}
+
+
+uint32_t
+GeneralMessage::GetNNetlinkAttribute (void)const
+{
+  return m_attributes.size ();
+}
+NetlinkAttribute
+GeneralMessage::GetNetlinkAttribute (uint32_t index)const
+{
+  NS_ASSERT(index < GetNNetlinkAttribute ());
+  return m_attributes[index];
+}
+
+uint32_t
+GeneralMessage::GetAttributeSerializedSize (void) const
+{
+  uint32_t size = 0;
+
+  for (uint32_t i = 0; i < m_attributes.size (); i ++)
+    {
+      size += m_attributes[i].GetSerializedSize ();
+    }
+  return size;
+}
+bool
+GeneralMessage::GetAttributeByType (NetlinkAttribute& attr, uint16_t type)
+{
+  for (uint32_t i = 0; i < m_attributes.size (); i ++)
+    {
+      if (type == m_attributes[i].GetAttrType ())
+        {
+          attr = m_attributes[i];
+          return true;
+        }
+    }
+  return false;  
+}
+void
+GeneralMessage::AppendAttribute (NetlinkAttribute v)
+{
+  m_attributes.push_back (v);
+}
+
+void
+GeneralMessage::SerializeAttribute (Buffer::Iterator& start) const
+{
+  for (uint32_t i = 0; i < m_attributes.size (); i ++)
+    {
+      m_attributes[i].Serialize (start);
+    }
+}
+
+void
+GeneralMessage::PrintAttribute (std::ostream &os) const
+{
+  for (uint32_t i = 0; i < m_attributes.size (); i ++)
+    {
+      os << " ----Attribute (" << i << "):";
+      m_attributes[i].Print(os);
+    }
+}
+
+/***********************************************************************************
+* \ InterfaceInfoMessage
+***********************************************************************************/
+InterfaceInfoMessage::InterfaceInfoMessage ()
+  : m_reserved (0),
+    m_deviceType (0),
+    m_interfaceIndex(0),
+    m_deviceFlags (0),
+    m_changeMask (0)
+{
+  memset ((void*)m_attributeTypes, 0, sizeof (m_attributeTypes));
+  m_attributeTypes[IFL_A_UNSPEC] = UNSPEC;
+  m_attributeTypes[IFL_A_ADDRESS] = ADDRESS;
+  m_attributeTypes[IFL_A_BROADCAST] = ADDRESS;
+  m_attributeTypes[IFL_A_IFNAME] = STRING;
+  m_attributeTypes[IFL_A_MTU] = U32;
+  m_attributeTypes[IFL_A_LINK] = U32;
+  m_attributeTypes[IFL_A_QDISC] = U8;
+  m_attributeTypes[IFL_A_STATS] = UNSPEC;
+  m_attributeTypes[IFL_A_COST] = UNSPEC;
+}
+InterfaceInfoMessage::~InterfaceInfoMessage ()
+{}
+void
+InterfaceInfoMessage::SetDeviceType (uint16_t type)
+{
+  m_deviceType = type;
+}
+void
+InterfaceInfoMessage::SetInterfaceIndex (int32_t index)
+{
+  m_interfaceIndex = index;
+}
+void
+InterfaceInfoMessage::SetDeviceFlags (uint32_t flags)
+{
+  m_deviceFlags = flags;
+}
+void
+InterfaceInfoMessage::SetChangeMask (uint32_t mask)
+{
+  m_changeMask = mask;
+}
+uint16_t
+InterfaceInfoMessage::GetDeviceType (void) const
+{
+  return m_deviceType;
+}
+int32_t
+InterfaceInfoMessage::GetInterfaceIndex (void) const
+{
+  return m_interfaceIndex;
+}
+uint32_t
+InterfaceInfoMessage::GetDeviceFlags (void) const
+{
+  return m_deviceFlags;
+}
+uint32_t
+InterfaceInfoMessage::GetChangeMask (void) const
+{
+  return m_changeMask;
+}
+TypeId 
+InterfaceInfoMessage::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::InterfaceInfoMessage")
+    .SetParent<GeneralMessage> ()
+    .AddConstructor<InterfaceInfoMessage> ()
+    ;
+  return tid;
+}
+TypeId 
+InterfaceInfoMessage::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+InterfaceInfoMessage::Print (std::ostream &os) const
+{  
+  os << " ----InterfaceInfoMessage ("
+     << "deviceType: " << m_deviceType << " "
+     << "interfaceIndex: " << m_interfaceIndex << " "
+     << "deviceFlags: " << m_deviceFlags << " "
+     << "changeMask: " << m_changeMask << ")" ;
+  PrintAttribute (os);
+}
+uint32_t 
+InterfaceInfoMessage::GetSerializedSize (void) const
+{
+  return NETLINK_INTERFACE_SIZE + GetAttributeSerializedSize ();
+}
+
+void
+InterfaceInfoMessage::Serialize (Buffer::Iterator& start) const
+{
+  start.WriteU8 (m_family);
+  start.WriteU8 (m_reserved);
+  start.WriteU16 (m_deviceType);
+  start.WriteU32 (m_interfaceIndex);
+  start.WriteU32 (m_deviceFlags);
+  start.WriteU32 (m_changeMask);
+
+  SerializeAttribute (start);
+}
+uint32_t
+InterfaceInfoMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
+{
+  m_family = start.ReadU8 ();
+  m_reserved = start.ReadU8 ();
+  m_deviceType = start.ReadU16 ();
+  m_interfaceIndex = start.ReadU32 ();
+  m_deviceFlags = start.ReadU32 ();
+  m_changeMask = start.ReadU32 ();
+
+  len -= NETLINK_INTERFACE_SIZE;
+
+  while (len)
+    {
+      NetlinkAttribute attr;
+
+      len -= attr.Deserialize (start, m_attributeTypes);
+      m_attributes.push_back (attr);
+    }
+
+  return GetSerializedSize ();
+}
+
+
+
+/***********************************************************************************
+* \InterfaceAddressMessage
+***********************************************************************************/
+InterfaceAddressMessage::InterfaceAddressMessage ()
+  : m_length (0),
+    m_flags (0),
+    m_scope (0),
+    m_index(0)
+{
+  memset ((void*)m_attributeTypes, 0, sizeof (m_attributeTypes));
+  m_attributeTypes[IF_A_UNSPEC] = UNSPEC;
+  m_attributeTypes[IF_A_ADDRESS] = ADDRESS;
+  m_attributeTypes[IF_A_LOCAL] = ADDRESS;
+  m_attributeTypes[IF_A_LABEL] = STRING;
+  m_attributeTypes[IF_A_BROADCAST] = ADDRESS;
+  m_attributeTypes[IF_A_ANYCAST] = ADDRESS;
+  m_attributeTypes[IF_A_CACHEINFO] = UNSPEC;
+  m_attributeTypes[IF_A_MULTICAST] = ADDRESS;
+}
+InterfaceAddressMessage::~InterfaceAddressMessage ()
+{
+}
+void
+InterfaceAddressMessage::SetFamily (uint8_t family)
+{
+  m_family = family;
+}
+void
+InterfaceAddressMessage::SetLength (uint8_t length)
+{
+  m_length = length;
+}
+void
+InterfaceAddressMessage::SetFlags (uint8_t flags)
+{
+  m_flags = flags;
+}
+void
+InterfaceAddressMessage::SetScope (uint8_t scope)
+{
+  m_scope = scope;
+}
+void
+InterfaceAddressMessage::SetInterfaceIndex (int32_t index)
+{
+  m_index = index;
+}
+
+uint8_t
+InterfaceAddressMessage::GetFamily (void) const
+{
+  return m_family;
+}
+uint8_t
+InterfaceAddressMessage::GetLength (void) const
+{
+  return m_length;
+}
+uint8_t
+InterfaceAddressMessage::GetFlags (void) const
+{
+  return m_flags;
+}
+uint8_t
+InterfaceAddressMessage::GetScope (void) const
+{
+  return m_scope;
+}
+int32_t
+InterfaceAddressMessage::GetInterfaceIndex (void) const
+{
+  return m_index;
+}
+
+TypeId 
+InterfaceAddressMessage::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::InterfaceAddressMessage")
+    .SetParent<GeneralMessage> ()
+    .AddConstructor<InterfaceAddressMessage> ()
+    ;
+  return tid;
+}
+TypeId 
+InterfaceAddressMessage::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+InterfaceAddressMessage::Print (std::ostream &os) const
+{  
+  os << " ----InterfaceAddressMessage ("
+     << "family: " << (uint32_t)m_family << " "
+     << "length: " << (uint32_t)m_length << " "
+     << "flags: " << (uint32_t)m_flags << " "
+     << "scope: " << (uint32_t)m_scope << " "
+     << "index: " << m_index << ")";
+  PrintAttribute (os);
+}
+uint32_t 
+InterfaceAddressMessage::GetSerializedSize (void) const
+{
+  return NETLINK_ADDRESS_SIZE + GetAttributeSerializedSize ();
+}
+
+void
+InterfaceAddressMessage::Serialize (Buffer::Iterator& start) const
+{
+  start.WriteU8 (m_family);
+  start.WriteU8 (m_length);
+  start.WriteU8 (m_flags);
+  start.WriteU8 (m_scope);
+  start.WriteU32 (m_index);
+
+  SerializeAttribute(start);
+}
+
+uint32_t
+InterfaceAddressMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
+{
+  m_family = start.ReadU8 ();
+  m_length = start.ReadU8 ();
+  m_flags = start.ReadU8 ();
+  m_scope = start.ReadU8 ();
+  m_index = start.ReadU32 ();
+
+  len -= NETLINK_ADDRESS_SIZE;
+
+  while (len)
+    {
+      NetlinkAttribute attr;
+
+      len -= attr.Deserialize (start, m_attributeTypes);
+      m_attributes.push_back (attr);
+    }
+
+  return GetSerializedSize ();
+}
+
+
+
+/***********************************************************************************
+* \ RouteMessage
+***********************************************************************************/
+RouteMessage::RouteMessage ()
+  : m_dstLen (0),
+    m_srcLen (0),
+    m_tos (0),
+    m_tableId (0),
+    m_protocol(0),
+    m_scope (0),
+    m_type (0),
+    m_flags (0)
+{
+  memset ((void*)m_attributeTypes, 0, sizeof (m_attributeTypes));
+  m_attributeTypes[RT_A_UNSPEC] = UNSPEC;
+  m_attributeTypes[RT_A_DST] = ADDRESS;
+  m_attributeTypes[RT_A_SRC] = ADDRESS;
+  m_attributeTypes[RT_A_IIF] = U32;
+  m_attributeTypes[RT_A_OIF] = U32;
+  m_attributeTypes[RT_A_GATEWAY] = ADDRESS;
+  m_attributeTypes[RT_A_PRIORITY] = U8;
+  m_attributeTypes[RT_A_PREFSRC] = ADDRESS;
+  m_attributeTypes[RT_A_METRICS] = UNSPEC;
+  //others default value UNSPEC
+}
+RouteMessage::~RouteMessage ()
+{}
+
+void
+RouteMessage::SetFamily (uint8_t v)
+{
+  m_family = v;
+}
+void
+RouteMessage::SetDstLength (uint8_t v)
+{
+  m_dstLen = v;
+}
+void
+RouteMessage::SetSrcLength (uint8_t v)
+{
+  m_srcLen = v;
+}
+void
+RouteMessage::SetTos (uint8_t v)
+{
+  m_tos = v;
+}
+void
+RouteMessage::SetTableId (uint8_t v)
+{
+  m_tableId = v;
+}
+void
+RouteMessage::SetProtocol (uint8_t v)
+{
+  m_protocol = v;
+}
+void
+RouteMessage::SetScope (uint8_t v)
+{
+  m_scope = v;
+}
+void
+RouteMessage::SetType (uint8_t v)
+{
+  m_type = v;
+}
+void
+RouteMessage::SetFlags (uint32_t v)
+{
+  m_flags = v;
+}
+uint8_t
+RouteMessage::GetFamily (void) const
+{
+  return m_family;
+}
+uint8_t
+RouteMessage::GetDstLength (void) const
+{
+  return m_dstLen;
+}
+uint8_t
+RouteMessage::GetSrcLength (void) const
+{
+  return m_srcLen;
+}
+uint8_t
+RouteMessage::GetTos (void) const
+{
+  return m_tos;
+}
+uint8_t
+RouteMessage::GetTableId (void) const
+{
+  return m_tableId;
+}
+uint8_t
+RouteMessage::GetProtocol (void) const
+{
+  return m_protocol;
+}
+uint8_t
+RouteMessage::GetType (void) const
+{
+  return m_type;
+}
+uint8_t
+RouteMessage::GetScope (void) const
+{
+  return m_scope;
+}
+uint32_t
+RouteMessage::GetFlags (void) const
+{
+  return m_flags;
+}
+
+TypeId 
+RouteMessage::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::RouteMessage")
+    .SetParent<GeneralMessage> ()
+    .AddConstructor<RouteMessage> ()
+    ;
+  return tid;
+}
+TypeId 
+RouteMessage::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+RouteMessage::Print (std::ostream &os) const
+{  
+  os << " ----RouteMessage ("
+     << "family: " << (uint32_t)m_family << " "
+     << "dstLen: " << (uint32_t)m_dstLen << " "
+     << "srcLen: " << (uint32_t)m_srcLen << " "
+     << "tos: " << (uint32_t)m_tos << " "
+     << "tableId: " << (uint32_t)m_tableId << " "
+     << "protocol: " << (uint32_t)m_protocol << " "
+     << "scope: " << (uint32_t)m_scope << " "
+     << "type: " << (uint32_t)m_type << " "
+     << "flags: " << m_flags<< ")" ;
+  PrintAttribute (os);
+}
+uint32_t 
+RouteMessage::GetSerializedSize (void) const
+{
+  return NETLINK_ROUTE_SIZE + GetAttributeSerializedSize ();
+}
+
+void
+RouteMessage::Serialize (Buffer::Iterator& start) const
+{
+  start.WriteU8 (m_family);
+  start.WriteU8 (m_dstLen);
+  start.WriteU8 (m_srcLen);
+  start.WriteU8 (m_tos);
+  start.WriteU8 (m_tableId);
+  start.WriteU8 (m_protocol);
+  start.WriteU8 (m_scope);
+  start.WriteU8 (m_type);
+  start.WriteU32 (m_flags);
+
+  SerializeAttribute (start);
+}
+uint32_t
+RouteMessage::Deserialize (Buffer::Iterator& start, uint32_t len)
+{
+  m_family = start.ReadU8 ();
+  m_dstLen = start.ReadU8 ();
+  m_srcLen = start.ReadU8 ();
+  m_tos = start.ReadU8 ();
+  m_tableId = start.ReadU8 ();
+  m_protocol = start.ReadU8 ();
+  m_scope = start.ReadU8 ();
+  m_type = start.ReadU8 ();
+  m_flags = start.ReadU32 ();
+
+  len -= NETLINK_ROUTE_SIZE;
+
+  while (len)
+    {
+      NetlinkAttribute attr;
+
+      len -= attr.Deserialize (start, m_attributeTypes);
+      m_attributes.push_back (attr);
+    }
+
+  return GetSerializedSize ();
+}
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-message-route.h	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,388 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#ifndef NETLINK_MESSAGE_ROUTE_H
+#define NETLINK_MESSAGE_ROUTE_H
+
+#include "ns3/object-base.h"
+#include "ns3/address.h"
+#include "netlink-attribute.h"
+#include <string>
+
+namespace ns3 {
+
+/*
+* this file define some netlink message of NETLINK_ROUTE protocol,
+* there are mainly three types:interface address, interface info, route entry
+* just implemented them for quagga porting.
+*/
+  
+
+
+/**
+* \Types of messages,here we only define the route message types quagga used
+*/
+enum NetlinkRtmType_e {
+  NETLINK_RTM_BASE = 16,
+
+  NETLINK_RTM_NEWLINK = 16,
+  NETLINK_RTM_DELLINK,
+  NETLINK_RTM_GETLINK,
+  NETLINK_RTM_SETLINK,
+
+  NETLINK_RTM_NEWADDR = 20,
+  NETLINK_RTM_DELADDR,
+  NETLINK_RTM_GETADDR,
+
+  NETLINK_RTM_NEWROUTE = 24,
+  NETLINK_RTM_DELROUTE,
+  NETLINK_RTM_GETROUTE,
+
+  NETLINK_RTM_MAX,
+};  
+
+/**
+* \Types of netlink groups,here we only define types quagga used
+*/
+enum NetlinkRtmGroup_e {
+  NETLINK_RTM_GRP_LINK = 1,
+  NETLINK_RTM_GRP_IPV4_IFADDR = 0x10,
+  NETLINK_RTM_GRP_IPV4_ROUTE = 0x40,
+  RTMGRP_IPV6_IFADDR = 0x100,
+  RTMGRP_IPV6_ROUTE = 0x400,
+};
+
+class NetlinkPayload :public ObjectBase
+{
+public:
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const = 0;
+  virtual void Serialize (Buffer::Iterator& start) const = 0;
+  virtual void Print (std::ostream &os) const = 0;
+  virtual uint32_t GetSerializedSize (void) const = 0;
+};
+
+/***
+ General form of address family dependent message.
+
+  struct rtgenmsg
+  {
+    unsigned char		rtgen_family;
+  };
+**/
+
+class GeneralMessage : public NetlinkPayload
+{
+public:
+  GeneralMessage ();
+  virtual ~GeneralMessage ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Serialize (Buffer::Iterator& start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator& start);
+  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+
+  
+  virtual uint32_t GetNNetlinkAttribute (void)const;
+  virtual NetlinkAttribute GetNetlinkAttribute (uint32_t index)const;
+  virtual void AppendAttribute (NetlinkAttribute v);
+  virtual void SerializeAttribute (Buffer::Iterator& start) const;
+  virtual void PrintAttribute (std::ostream &os) const;
+  virtual uint32_t GetAttributeSerializedSize (void) const;
+  virtual bool GetAttributeByType (NetlinkAttribute& attr, uint16_t type);
+
+
+  void SetFamily (uint8_t v);
+  uint8_t GetFamily (void) const;
+
+private:
+  static const int NETLINK_GENMSG_SIZE = 1; /* size of the struct rtgenmsg */  
+protected:
+  uint8_t m_family;   //always set to AF_UNSPEC
+  //attribute can exist or not
+  std::vector<NetlinkAttribute> m_attributes;
+};
+
+
+
+/**
+* \brief Link layer specific messages
+*
+* struct ifinfomsg
+* passes link level specific information, not dependent
+* on network protocol.
+*
+  struct ifinfomsg
+  {
+    unsigned char	ifi_family;
+    unsigned char	__ifi_pad;
+    unsigned short	ifi_type;
+    int		ifi_index;	
+    unsigned	ifi_flags;
+    unsigned	ifi_change;
+  };
+*/
+class InterfaceInfoMessage : public GeneralMessage
+{
+public:
+  InterfaceInfoMessage ();
+  virtual ~InterfaceInfoMessage ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Serialize (Buffer::Iterator& start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+
+  enum IflAttr_e {
+    IFL_A_UNSPEC,
+    IFL_A_ADDRESS,
+    IFL_A_BROADCAST,
+    IFL_A_IFNAME,
+    IFL_A_MTU,
+    IFL_A_LINK,
+    IFL_A_QDISC,
+    IFL_A_STATS,
+    IFL_A_COST,
+    IFL_A_PRIORITY,
+    IFL_A_MASTER,
+    IFL_A_WIRELESS,		
+    IFL_A_PROTINFO,
+    IFL_A_TXQLEN,
+    IFL_A_MAP,
+    IFL_A_WEIGHT,
+    IFL_A_OPERSTATE,
+    IFL_A_LINKMODE,
+    IFL_A_MAX,
+  };
+
+  enum Type_e {
+    UP = 1,
+    BROADCAST = 2,
+    DBG = 4,
+  };
+
+  void SetDeviceType (uint16_t type);
+  void SetInterfaceIndex (int32_t index);
+  void SetDeviceFlags (uint32_t index);
+  void SetChangeMask (uint32_t mask);
+
+  uint16_t GetDeviceType (void) const;
+  int32_t GetInterfaceIndex (void) const;
+  uint32_t GetDeviceFlags (void) const;
+  uint32_t GetChangeMask (void) const;
+private:
+  static const int NETLINK_INTERFACE_SIZE = 16; /* size of the struct ifinfomsg */
+  uint8_t m_reserved; //not used
+  uint16_t m_deviceType;
+  int32_t m_interfaceIndex;
+  uint32_t m_deviceFlags;
+  uint32_t m_changeMask;
+  NetlinkAttributeValueType m_attributeTypes[IFL_A_MAX];
+};
+
+
+
+
+/**
+* \brief Interface address.
+*
+  struct ifaddrmsg
+  {
+  unsigned char	ifa_family;
+  unsigned char	ifa_prefixlen;
+  unsigned char	ifa_flags;
+  unsigned char	ifa_scope;
+  int		ifa_index;
+  };
+*/
+
+class InterfaceAddressMessage : public GeneralMessage
+{
+public:
+  InterfaceAddressMessage ();
+  virtual ~InterfaceAddressMessage ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Serialize (Buffer::Iterator& start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+
+  enum IfAttr_e {
+    IF_A_UNSPEC,
+    IF_A_ADDRESS,
+    IF_A_LOCAL,
+    IF_A_LABEL,
+    IF_A_BROADCAST,
+    IF_A_ANYCAST,
+    IF_A_CACHEINFO,
+    IF_A_MULTICAST,
+    IF_A_MAX
+  };
+
+  enum {
+    F_SECONDARY = 0x01,
+    F_PERMANENT = 0x80,
+    F_DEPRECATED = 0x20,
+    F_TENTATIVE = 0x40
+  };
+  enum {
+    SCOPE_UNIVERSE = 0,
+    SCOPE_SITE = 200,
+    SCOPE_LINK = 253,
+    SCOPE_HOST = 254
+  };
+
+
+  void SetFamily (uint8_t family);
+  void SetLength (uint8_t length);
+  void SetFlags (uint8_t flags);
+  void SetScope (uint8_t scope);
+  void SetInterfaceIndex (int32_t index);
+
+  uint8_t GetFamily (void) const;
+  uint8_t GetLength (void) const;
+  uint8_t GetFlags (void) const;
+  uint8_t GetScope (void) const;
+  int32_t GetInterfaceIndex (void) const;
+
+private:
+  static const int NETLINK_ADDRESS_SIZE = 8; /* size of the struct ifaddrmsg */
+  uint8_t m_length;
+  uint8_t m_flags;
+  uint8_t m_scope;
+  int32_t m_index;
+  NetlinkAttributeValueType m_attributeTypes[IF_A_MAX];
+};
+
+
+/**
+* \brief Definitions used in routing table administration.
+*
+  struct rtmsg
+  {
+    unsigned char		rtm_family;
+    unsigned char		rtm_dst_len;
+    unsigned char		rtm_src_len;
+    unsigned char		rtm_tos;
+
+    unsigned char		rtm_table;	// Routing table id 
+    unsigned char		rtm_protocol;	//Routing protocol; 
+    unsigned char		rtm_scope;	
+    unsigned char		rtm_type;	
+
+    unsigned		rtm_flags;
+  };
+*/
+
+class RouteMessage : public GeneralMessage
+{
+public:
+  RouteMessage ();
+  virtual ~RouteMessage ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Serialize (Buffer::Iterator& start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator& start, uint32_t len);
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+
+  uint8_t GetFamily (void) const;
+  uint8_t GetDstLength (void) const;
+  uint8_t GetSrcLength (void) const;
+  uint8_t GetTos (void) const;
+  uint8_t GetTableId (void) const;
+  uint8_t GetProtocol(void) const;
+  uint8_t GetType (void) const;
+  uint8_t GetScope (void) const;
+  uint32_t GetFlags (void) const;
+  void SetFamily (uint8_t v);
+  void SetDstLength (uint8_t v);
+  void SetSrcLength (uint8_t v);
+  void SetTos (uint8_t v);
+  void SetTableId (uint8_t v);
+  void SetProtocol (uint8_t v);
+  void SetScope (uint8_t v);
+  void SetType (uint8_t v);
+  void SetFlags (uint32_t v);
+
+  enum RtProtocol_e {
+    RT_PROT_UNSPEC = 0,
+  };
+
+  enum RtFlags_e {
+    RT_F_CLONED = 0x200,
+  };
+
+  enum RtScope_e {
+    RT_SCOPE_UNIVERSE = 0,
+    RT_SCOPE_LINK = 253,
+  };
+
+  enum RtClass_e {
+    RT_TABLE_UNSPEC = 0,
+    RT_TABLE_MAIN = 254,
+  };
+
+  enum RtAttr_e {
+    RT_A_UNSPEC,
+    RT_A_DST,
+    RT_A_SRC,
+    RT_A_IIF,
+    RT_A_OIF,
+    RT_A_GATEWAY,
+    RT_A_PRIORITY,
+    RT_A_PREFSRC,
+    RT_A_METRICS,
+    RT_A_MULTIPATH,
+    RT_A_PROTOINFO,
+    RT_A_FLOW,
+    RT_A_CACHEINFO,
+    RT_A_SESSION,
+    RT_A_MP_ALGO,
+    RT_A_TABLE,
+    RT_A_MAX
+  };
+
+
+private:
+  static const int NETLINK_ROUTE_SIZE = 12; /* size of the struct rtmsg */
+  uint8_t m_dstLen;
+  uint8_t m_srcLen;
+  uint8_t m_tos;
+  uint8_t m_tableId;
+  uint8_t m_protocol;
+  uint8_t m_scope;
+  uint8_t m_type;
+  uint32_t m_flags;
+  NetlinkAttributeValueType m_attributeTypes[RT_A_MAX];
+};
+
+}; // namespace ns3
+
+#endif /* NETLINK_MESSAGE_ROUTE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-message.cc	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,672 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#include "netlink-message.h"
+#include "ns3/address-utils.h"
+#include "ns3/log.h"
+
+NS_LOG_COMPONENT_DEFINE ("NetlinkMessage");
+
+namespace ns3 {
+
+/***********************************************************************************
+* \ NetlinkMessageHeader
+***********************************************************************************/
+NS_OBJECT_ENSURE_REGISTERED (NetlinkMessageHeader);
+NS_OBJECT_ENSURE_REGISTERED (NetlinkMessage);
+
+NetlinkMessageHeader::NetlinkMessageHeader ()
+  : m_nlmsgLen (16),
+    m_nlmsgType (0),
+    m_nlmsgFlags (0),
+    m_nlmsgSeq (0),
+    m_nlmsgPid (0)
+{}
+
+NetlinkMessageHeader::NetlinkMessageHeader (uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid)
+  : m_nlmsgLen (16),
+    m_nlmsgType (type),
+    m_nlmsgFlags (flags),
+    m_nlmsgSeq (seq),
+    m_nlmsgPid (pid)
+{}
+
+void
+NetlinkMessageHeader::SetMsgLen (uint32_t v)
+{
+  m_nlmsgLen = v;
+}
+void
+NetlinkMessageHeader::SetMsgFlags (uint16_t v)
+{
+  m_nlmsgFlags = v;
+}
+void
+NetlinkMessageHeader::SetMsgType (uint16_t v)
+{
+  m_nlmsgType = v;
+}
+void
+NetlinkMessageHeader::SetMsgSeq (uint32_t v)
+{
+  m_nlmsgSeq = v;
+}
+void
+NetlinkMessageHeader::SetMsgPid (uint32_t v)
+{
+  m_nlmsgPid = v;
+}
+uint16_t
+NetlinkMessageHeader::GetMsgFlags (void) const
+{
+  return m_nlmsgFlags;
+}
+uint32_t 
+NetlinkMessageHeader::GetMsgLen (void) const
+{
+  return m_nlmsgLen;
+}
+uint16_t 
+NetlinkMessageHeader::GetMsgType (void) const
+{
+  return m_nlmsgType;
+}
+uint32_t
+NetlinkMessageHeader::GetMsgSeq (void) const
+{
+  return m_nlmsgSeq;
+}
+uint32_t 
+NetlinkMessageHeader::GetMsgPid (void) const
+{
+  return m_nlmsgPid;
+}
+uint32_t
+NetlinkMessageHeader::GetHeaderSize ()
+{
+  return NETLINK_MSG_HEADER_SIZE;
+}
+uint32_t
+NetlinkMessageHeader::GetPayloadSize (void) const
+{
+  return NETLINK_MSG_ALIGN (m_nlmsgLen - NETLINK_MSG_HEADER_SIZE);
+}
+
+TypeId 
+NetlinkMessageHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NetlinkMessageHeader")
+    .SetParent<Header> ()
+    .AddConstructor<NetlinkMessageHeader> ()
+    ;
+  return tid;
+}
+TypeId 
+NetlinkMessageHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+NetlinkMessageHeader::Print (std::ostream &os) const
+{
+  os << "NetlinkMessageHeader "
+     << "len: " << m_nlmsgLen << " "
+     << "flags: " << m_nlmsgFlags << " "
+     << "type: " << m_nlmsgType << " "
+     << "seq: " << m_nlmsgSeq << " "
+     << "pid: " << m_nlmsgPid;
+}
+
+uint32_t 
+NetlinkMessageHeader::GetSerializedSize (void) const
+{
+  /* this is the size of an nlmsghdr payload. */
+  return NETLINK_MSG_HEADER_SIZE;
+}
+
+void
+NetlinkMessageHeader::Serialize (Buffer::Iterator& start) const
+{
+  start.WriteU32 (m_nlmsgLen);
+  start.WriteU16 (m_nlmsgType);
+  start.WriteU16 (m_nlmsgFlags);
+  start.WriteU32 (m_nlmsgSeq);
+  start.WriteU32 (m_nlmsgPid);
+}
+
+uint32_t
+NetlinkMessageHeader::Deserialize (Buffer::Iterator& start)
+{
+  m_nlmsgLen = start.ReadU32 ();
+  m_nlmsgType = start.ReadU16 ();
+  m_nlmsgFlags = start.ReadU16 ();
+  m_nlmsgSeq = start.ReadU32 ();
+  m_nlmsgPid = start.ReadU32 ();
+
+  return GetSerializedSize ();
+}
+
+
+
+
+/***********************************************************************************
+* \ NetlinkMessageError
+***********************************************************************************/
+
+NetlinkMessageError::NetlinkMessageError ()
+  : m_error (0)
+{
+}
+NetlinkMessageError::~NetlinkMessageError ()
+{}
+void 
+NetlinkMessageError::SetError (int32_t v)
+{
+  m_error = v;
+}
+int32_t
+NetlinkMessageError::GetError (void) const
+{
+  return m_error;
+}
+void
+NetlinkMessageError::SetMsg (NetlinkMessageHeader v)
+{
+  m_msg = v;
+}
+NetlinkMessageHeader
+NetlinkMessageError::GetMsg (void) const
+{
+  return m_msg;
+}
+
+TypeId 
+NetlinkMessageError::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NetlinkMessageError")
+    .SetParent<NetlinkPayload> ()
+    .AddConstructor<NetlinkMessageError> ()
+    ;
+  return tid;
+}
+
+TypeId 
+NetlinkMessageError::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+NetlinkMessageError::Print (std::ostream &os) const
+{  
+  os << "----NetlinkMessageError "
+     << "error: " << m_error << " "
+     << "msg:( ";
+  m_msg.Print(os);
+  os << " )";
+}
+
+uint32_t 
+NetlinkMessageError::GetSerializedSize (void) const
+{
+  /* this is the size of an nlmsgerr payload. */
+  return NETLINK_MSG_ERROR_SIZE;
+}
+
+void
+NetlinkMessageError::Serialize (Buffer::Iterator& start) const
+{
+  start.WriteU32 (m_error);
+  m_msg.Serialize (start);
+}
+
+uint32_t
+NetlinkMessageError::Deserialize (Buffer::Iterator& start)
+{  
+  m_error = start.ReadU32 ();
+  m_msg.Deserialize (start);
+  
+  return GetSerializedSize ();
+}
+
+
+
+
+/***********************************************************************************
+* \ NetlinkMessage
+***********************************************************************************/
+NetlinkMessage::NetlinkMessage ()
+{}
+
+void
+NetlinkMessage::SetHeader (NetlinkMessageHeader hdr)
+{
+  m_hdr = hdr;
+}
+NetlinkMessageHeader
+NetlinkMessage::GetHeader (void)const
+{
+  return m_hdr;
+}
+void
+NetlinkMessage::SetGeneralMessage (GeneralMessage genmsg)
+{
+  m_genmsg = genmsg;
+  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + genmsg.GetSerializedSize ());
+}
+void
+NetlinkMessage::SetErrorMessage (NetlinkMessageError errmsg)
+{
+  m_errorMessage = errmsg;
+  m_hdr.SetMsgLen(m_hdr.GetSerializedSize () + errmsg.GetSerializedSize ());
+}
+// the type is one of RTM_NEWLINK,RTM_DELLINK,RTM_GETLINK
+void
+NetlinkMessage::SetInterfaceInfoMessage (InterfaceInfoMessage v)
+{
+  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
+  m_interfaceTemplate = v;
+}
+// the type is one of RTM_NEWADDR,RTM_DELADDR,RTM_GETADDR
+void NetlinkMessage::SetInterfaceAddressMessage (InterfaceAddressMessage v)
+{
+  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
+  m_addressTemplate = v;
+}
+// the type  is one of RTM_NEWROUTE,RTM_DELROUTE,RTM_GETROUTE
+void NetlinkMessage::SetRouteMessage (RouteMessage v)
+{
+  m_hdr.SetMsgLen (m_hdr.GetSerializedSize () + v.GetSerializedSize ());
+  m_routeTemplate = v;
+}
+GeneralMessage
+NetlinkMessage::GetGeneralMessage (void) const
+{
+  return m_genmsg;
+}
+NetlinkMessageError
+NetlinkMessage::GetErrorMessage (void) const
+{
+  return m_errorMessage;
+}
+InterfaceInfoMessage
+NetlinkMessage::GetInterfaceInfoMessage (void) const
+{
+  return m_interfaceTemplate;
+}
+InterfaceAddressMessage
+NetlinkMessage::GetInterfaceAddressMessage (void) const
+{
+  return m_addressTemplate;
+}
+RouteMessage
+NetlinkMessage::GetRouteMessage (void) const
+{
+  return m_routeTemplate;
+}
+bool
+NetlinkMessage::IsMessageNetlinkControl (uint16_t type)
+{
+  return (type < NETLINK_RTM_BASE);
+}
+bool
+NetlinkMessage::IsMessageNetlinkRoute (uint16_t type)
+{
+  return (type >= NETLINK_RTM_BASE && type < NETLINK_RTM_MAX);
+}
+bool
+NetlinkMessage::IsMessageAddress (uint16_t type)
+{
+  return (type >= NETLINK_RTM_NEWADDR && type <= NETLINK_RTM_GETADDR);
+}
+bool
+NetlinkMessage::IsMessageInterface (uint16_t type)
+{
+  return (type >= NETLINK_RTM_NEWLINK && type <= NETLINK_RTM_SETLINK);
+}
+bool
+NetlinkMessage::IsMessageRoute (uint16_t type)
+{
+  return (type >= NETLINK_RTM_NEWROUTE && type <= NETLINK_RTM_GETROUTE);
+}
+bool
+NetlinkMessage::IsMessageTypeGet (uint16_t type)
+{
+  return ((( type - NETLINK_RTM_BASE)&3) == 2);
+}
+bool
+NetlinkMessage::IsMessageFlagsAck (uint16_t flags)
+{
+  return (flags & NETLINK_MSG_F_ACK) ? true : false;
+}
+bool
+NetlinkMessage::IsMessageFlagsRequest (uint16_t flags)
+{
+  return (flags & NETLINK_MSG_F_REQUEST) ? true : false;
+}
+bool
+NetlinkMessage::IsMessageFlagsDump (uint16_t flags)
+{
+  return (flags & NETLINK_MSG_F_DUMP) ? true : false;
+}
+
+NetlinkMessage::operator MultipartNetlinkMessage (void) const
+{
+  MultipartNetlinkMessage multi_nlmsg;
+  multi_nlmsg.AppendMessage (*this);
+  return multi_nlmsg;
+}
+
+TypeId 
+NetlinkMessage::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NetlinkMessage")
+    .SetParent<Header> ()
+    .AddConstructor<NetlinkMessage> ()
+    ;
+  return tid;
+}
+TypeId 
+NetlinkMessage::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+uint32_t
+NetlinkMessage::GetTotalSize (void) const
+{
+  return NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ());
+}
+
+uint32_t
+NetlinkMessage::GetMsgSize (void) const
+{
+  return m_hdr.GetMsgLen ();
+}
+
+uint32_t
+NetlinkMessage::GetPayloadSize (void) const
+{
+  return m_hdr.GetPayloadSize ();
+}
+uint16_t
+NetlinkMessage::GetMsgType (void) const
+{
+  return m_hdr.GetMsgType ();
+}
+
+uint8_t
+NetlinkMessage::GetFamily(void) const
+{
+  if (IsMessageTypeGet (GetMsgType ()))
+    {
+      NS_LOG_DEBUG ("TypeGetMsg");
+    }
+  if (IsMessageAddress (m_hdr.GetMsgType ()))
+    {
+      return m_addressTemplate.GetFamily ();
+    }
+  else if (IsMessageInterface(m_hdr.GetMsgType ()))
+    {
+      return m_interfaceTemplate.GetFamily ();
+    }
+  else if (IsMessageRoute(m_hdr.GetMsgType ()))
+    {
+      return m_routeTemplate.GetFamily ();
+    }
+  else if (IsMessageFlagsDump (m_hdr.GetMsgFlags ()))
+    {
+      return m_genmsg.GetFamily (); //value is said to be always set to AF_UNSPEC
+    }
+  else
+    {
+      NS_LOG_WARN ("Netlink message type not supported, return AF_UNSPEC");
+      return 0;
+    }
+}
+
+void 
+NetlinkMessage::Print (std::ostream &os) const
+{
+  uint16_t type = m_hdr.GetMsgType ();
+
+  os << "NetlinkMessage  ";
+  os << " ----Header:(";
+  m_hdr.Print(os);
+  os << ")";
+
+  if (type == NETLINK_MSG_DONE )
+    {
+      os << "multipart message ends here";
+    }
+  else if (type == NETLINK_MSG_ERROR )
+    {
+      m_errorMessage.Print (os);
+    }
+  else if (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK)
+    {
+      m_genmsg.Print (os);
+    }  
+  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE)
+    {
+      m_routeTemplate.Print (os);
+    }
+  else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
+    {
+      m_addressTemplate.Print (os);
+    }
+  else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_DELLINK)
+    {
+      m_interfaceTemplate.Print (os);
+    }
+  else
+    {
+      os << "service not supported yet( " << type <<")";
+    }
+}
+uint32_t 
+NetlinkMessage::GetSerializedSize (void) const
+{
+  return NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ());
+}
+
+void
+NetlinkMessage::Serialize (Buffer::Iterator& start) const
+{
+  NS_LOG_FUNCTION (this);
+  //  Print (std::cout);
+  uint16_t type = m_hdr.GetMsgType ();
+
+  m_hdr.Serialize (start);
+
+  if (type == NETLINK_MSG_DONE)
+    {
+      //nothing done
+    }
+  else if (type == NETLINK_MSG_ERROR)
+    {
+      m_errorMessage.Serialize (start);
+    }  
+  else if (NetlinkMessage::IsMessageFlagsDump (m_hdr.GetMsgFlags ()) && 
+           (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK))
+    {
+      m_genmsg.Serialize (start);
+    }  
+  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
+    {
+      m_routeTemplate.Serialize (start);
+    }
+  else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
+    {
+      m_addressTemplate.Serialize (start);
+    }
+  else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_SETLINK)
+    {
+      m_interfaceTemplate.Serialize (start);
+    }
+  else
+    {
+    }  
+}
+
+
+uint32_t
+NetlinkMessage::Deserialize (Buffer::Iterator&start)
+{
+  uint32_t remaining;
+
+  m_hdr.Deserialize (start);
+  remaining = NETLINK_MSG_ALIGN (m_hdr.GetMsgLen ()) - m_hdr.GetSerializedSize ();
+  
+  //Deserialize service module
+  uint16_t type = GetMsgType ();
+  if (remaining)
+    {        
+      if (type == NETLINK_MSG_DONE)
+        {
+          //do nothing
+        }
+      else if (type == NETLINK_MSG_ERROR)
+        {
+          remaining -= m_errorMessage.Deserialize (start);
+        }      
+      else if (NetlinkMessage::IsMessageFlagsDump (m_hdr.GetMsgFlags()) &&
+               (type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETLINK))
+        {
+          remaining -= m_genmsg.Deserialize (start, remaining);
+        }
+      else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
+        {
+          remaining -= m_routeTemplate.Deserialize (start, remaining);
+        }
+      else if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
+        {
+          remaining -= m_addressTemplate.Deserialize (start, remaining);
+        }
+      else if (type == NETLINK_RTM_NEWLINK || type == NETLINK_RTM_SETLINK)
+        {
+          remaining -= m_interfaceTemplate.Deserialize (start, remaining);
+        }
+      else
+        {
+          //do nothing
+        }
+    }
+
+  return GetSerializedSize ();
+}
+
+
+/***********************************************************************************
+* \ MultipartNetlinkMessage
+***********************************************************************************/
+MultipartNetlinkMessage::MultipartNetlinkMessage ()
+{}
+
+TypeId 
+MultipartNetlinkMessage::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::MultipartNetlinkMessage")
+    .SetParent<Header> ()
+    .AddConstructor<MultipartNetlinkMessage> ()
+    ;
+  return tid;
+}
+TypeId 
+MultipartNetlinkMessage::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+void
+MultipartNetlinkMessage::Print (std::ostream &os) const
+{
+  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
+    {
+      m_netlinkMessages[i].Print (os);
+    }
+}
+uint32_t
+MultipartNetlinkMessage::GetSerializedSize (void) const
+{
+  uint32_t len = 0;
+
+  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
+    {
+      len +=  m_netlinkMessages[i].GetSerializedSize ();
+    }
+  return len;
+}
+void
+MultipartNetlinkMessage::Serialize (Buffer::Iterator start) const
+{
+  NS_LOG_FUNCTION ("Multi" << this);
+  for (uint32_t i = 0; i <  m_netlinkMessages.size (); i ++)
+    {
+      m_netlinkMessages[i].Serialize (start);
+    }
+}
+uint32_t
+MultipartNetlinkMessage::Deserialize (Buffer::Iterator start)
+{
+  while (1)
+    {
+      NetlinkMessage nlmsg;
+      nlmsg.Deserialize (start);
+      AppendMessage (nlmsg);
+
+      if (!(nlmsg.GetHeader ().GetMsgFlags () & NETLINK_MSG_F_MULTI))
+        {
+          break;
+        }
+
+      if (nlmsg.GetHeader ().GetMsgType() == NETLINK_MSG_DONE)
+        {
+          break;
+        }
+    }
+  return GetSerializedSize ();
+}
+
+void
+MultipartNetlinkMessage::AppendMessage (NetlinkMessage nlmsg)
+{
+  m_netlinkMessages.push_back (nlmsg);
+}
+
+void
+MultipartNetlinkMessage::Clear ()
+{
+  m_netlinkMessages.clear ();
+}
+
+uint32_t
+MultipartNetlinkMessage::GetNMessages (void) const
+{
+  return m_netlinkMessages.size ();
+}
+NetlinkMessage
+MultipartNetlinkMessage::GetMessage (uint32_t index) const
+{
+  NS_ASSERT(index < m_netlinkMessages.size ());
+  return m_netlinkMessages[index];
+}
+
+}; // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-message.h	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,256 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#ifndef NETLINK_MESSAGE_H
+#define NETLINK_MESSAGE_H
+
+#include "ns3/header.h"
+#include "ns3/address.h"
+#include "netlink-message-route.h"
+#include "netlink-attribute.h"
+
+
+namespace ns3 {
+  class NetlinkPayload;
+  class GeneralMessage;
+  class InterfaceAddressMessage;
+  class InterfaceInfoMessage;
+  class RouteMessage;
+  class MultipartNetlinkMessage;
+
+/**
+* \brief The Netlink message structure for an netlink packet
+* 
+There are three levels to a Netlink message: The general Netlink
+message header, the IP service specific template, and the IP service
+specific data.
+
+0                   1                   2                   3
+0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|                                                               |
+|                   Netlink message header                      |
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|                                                               |
+|                  IP Service Template                          |
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|                                                               |
+|                  IP Service specific data in TLVs             |
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+  enum NetlinkMessageFlag
+  {
+    NETLINK_MSG_F_REQUEST = 1,  // It is request message.
+    NETLINK_MSG_F_MULTI = 2,    // Multipart message, terminated by NETLINK_MSG_DONE
+    NETLINK_MSG_F_ACK = 4,      // Reply with ack, with zero or error code
+    NETLINK_MSG_F_ECHO = 8,     // Echo this request 
+
+    /* Modifiers to Get request */
+    NETLINK_MSG_F_ROOT = 0x100,        // specify tree root
+    NETLINK_MSG_F_MATCH = 0x200,       // return all matching
+    NETLINK_MSG_F_ATOMIC = 0x400,      // atomic Get =
+    NETLINK_MSG_F_DUMP = (NETLINK_MSG_F_ROOT|NETLINK_MSG_F_MATCH),
+
+    /* Modifiers to NEW request */
+    NETLINK_MSG_F_REPLACE = 0x100, // Override existing = 
+    NETLINK_MSG_F_EXCL = 0x200,   // Do not touch, if it exists
+    NETLINK_MSG_F_CREATE = 0x400,  // Create, if it does not exist
+    NETLINK_MSG_F_APPEND = 0x800,  // Add to end of list = 
+  };
+
+  enum NetlinkMessageType
+  {
+    NETLINK_MSG_NOOP = 0x1,          // Nothing.
+    NETLINK_MSG_ERROR = 0x2,         // Error
+    NETLINK_MSG_DONE = 0x3,          // End of a dump
+    NETLINK_MSG_OVERRUN = 0x4,       // Data lost
+    NETLINK_MSG_MIN_TYPE = 0x10,     // < 0x10: reserved control messages
+  };
+
+#define NETLINK_MSG_ALIGNTO 4
+#define NETLINK_MSG_ALIGN(X)    (((X)+NETLINK_MSG_ALIGNTO-1) & ~(NETLINK_MSG_ALIGNTO-1) )
+
+class NetlinkMessageHeader : public ObjectBase
+{
+public:
+  NetlinkMessageHeader ();
+  NetlinkMessageHeader (uint16_t type, uint16_t flags, uint32_t seq, uint32_t pid);
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  void Print (std::ostream &os) const;
+  uint32_t GetSerializedSize (void) const;
+  void Serialize (Buffer::Iterator& start) const;
+  uint32_t Deserialize (Buffer::Iterator& start);
+
+  void SetMsgLen (uint32_t v);
+  void SetMsgFlags (uint16_t v);
+  void SetMsgType (uint16_t v);
+  void SetMsgSeq (uint32_t v);
+  void SetMsgPid (uint32_t v);
+  uint32_t GetMsgLen (void) const;
+  uint16_t GetMsgFlags (void) const;
+  uint16_t GetMsgType (void) const;
+  uint32_t GetMsgSeq (void) const;
+  uint32_t GetMsgPid (void) const;
+
+  static uint32_t GetHeaderSize ();
+  uint32_t GetPayloadSize (void) const;
+
+private:
+  static const uint32_t NETLINK_MSG_HEADER_SIZE = 16; /* size of the nlmsghdr field*/
+  uint32_t m_nlmsgLen;	/* Length of message including header */
+  uint16_t m_nlmsgType;	/* Message content */
+  uint16_t m_nlmsgFlags;	/* Additional flags */
+  uint32_t m_nlmsgSeq;	/* Sequence number */
+  uint32_t m_nlmsgPid;	/* Sending process PID */
+};
+
+/**
+* \brief The struct nlmsgerr
+*/
+class NetlinkMessageError : public NetlinkPayload
+{
+public:
+  NetlinkMessageError ();
+  virtual ~NetlinkMessageError();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Serialize (Buffer::Iterator& start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator& start);
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+
+  void SetError (int32_t v);
+  int32_t GetError (void) const;
+  void SetMsg(NetlinkMessageHeader v);
+  NetlinkMessageHeader GetMsg (void) const;
+
+private:
+  static const int NETLINK_MSG_ERROR_SIZE = 20; /* size of the nlmsgerror field*/
+  int32_t m_error;
+  NetlinkMessageHeader m_msg;        
+};
+
+
+class NetlinkMessage : public ObjectBase
+{
+public:
+  NetlinkMessage ();
+
+  static TypeId GetTypeId (void);
+  TypeId GetInstanceTypeId (void) const;
+  void Print (std::ostream &os) const;
+  uint32_t GetSerializedSize (void) const;
+  void Serialize (Buffer::Iterator& start) const;
+  uint32_t Deserialize (Buffer::Iterator& start);
+
+  operator MultipartNetlinkMessage (void) const;
+
+  uint32_t GetTotalSize (void) const;  //length of netlink message including padding
+  uint32_t GetMsgSize (void) const;    //length of netlink message not including padding
+  uint32_t GetPayloadSize (void) const; //length of message payload
+  uint16_t GetMsgType (void) const;
+  uint8_t GetFamily(void) const;
+
+  void SetHeader (NetlinkMessageHeader hdr);
+  NetlinkMessageHeader GetHeader (void) const;
+
+  //before set message body, should set header first
+  void SetErrorMessage (NetlinkMessageError errmsg);
+  void SetGeneralMessage (GeneralMessage genmsg);
+  void SetInterfaceInfoMessage (InterfaceInfoMessage v);
+  void SetInterfaceAddressMessage (InterfaceAddressMessage v);
+  void SetRouteMessage (RouteMessage v);
+  NetlinkMessageError GetErrorMessage (void) const;
+  GeneralMessage GetGeneralMessage (void) const;
+  InterfaceInfoMessage GetInterfaceInfoMessage (void) const;
+  InterfaceAddressMessage GetInterfaceAddressMessage (void) const;
+  RouteMessage GetRouteMessage (void) const;
+
+  /**
+  * \returns true if type was control type, false otherwise.
+  */
+  static bool IsMessageNetlinkControl (uint16_t type);
+  /**
+  * \returns true if type was netlink route, false otherwise.
+  */
+  static bool IsMessageNetlinkRoute (uint16_t type);
+  static bool IsMessageAddress (uint16_t type);
+  static bool IsMessageInterface (uint16_t type);
+  static bool IsMessageRoute (uint16_t type);
+  /**
+  * \returns true if type was GETxxx , false otherwise.
+  */
+  static bool IsMessageTypeGet (uint16_t type);
+  /**
+  * \returns true if flag has ack , false otherwise.
+  */
+  static bool IsMessageFlagsAck (uint16_t flags);
+  /**
+  * \returns true if flag has request , false otherwise.
+  */
+  static bool IsMessageFlagsRequest (uint16_t flags);
+  /**
+  * \returns true if flag has dump , false otherwise.
+  */
+  static bool IsMessageFlagsDump (uint16_t flags);
+
+private:
+  NetlinkMessageHeader m_hdr;
+
+  //only one type of messages below exists in real world application
+  NetlinkMessageError m_errorMessage;  
+  GeneralMessage m_genmsg;
+  InterfaceInfoMessage m_interfaceTemplate;
+  InterfaceAddressMessage m_addressTemplate;
+  RouteMessage m_routeTemplate;
+};
+
+class MultipartNetlinkMessage : public Header
+{
+public:
+  MultipartNetlinkMessage ();
+
+  static TypeId GetTypeId (void);
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  void AppendMessage (NetlinkMessage nlmsg);
+  void Clear();
+  uint32_t GetNMessages (void) const;
+  NetlinkMessage GetMessage (uint32_t index) const;
+
+private:
+  std::vector<NetlinkMessage> m_netlinkMessages;
+};
+
+}; // namespace ns3
+
+#endif /* NETLINK_MESSAGE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-socket-address.cc	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,121 @@
+/* -*-	Mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#include "netlink-socket-address.h"
+
+namespace ns3 {
+
+NetlinkSocketAddress::NetlinkSocketAddress (uint32_t pid, uint32_t groups)
+  : m_pid(pid),
+    m_groups(groups)
+{}
+
+NetlinkSocketAddress::NetlinkSocketAddress ()
+  : m_pid (0),
+    m_groups (0)
+{}
+
+NetlinkSocketAddress::~NetlinkSocketAddress ()
+{}
+
+void NetlinkSocketAddress::SetProcessID (uint32_t pid)
+{
+  m_pid = pid;
+}
+
+void NetlinkSocketAddress::SetGroupsMask (uint32_t mask)
+{
+  m_groups = mask;
+}
+
+uint32_t NetlinkSocketAddress::GetProcessID (void) const
+{
+  return m_pid;
+}
+
+uint32_t NetlinkSocketAddress::GetGroupsMask (void) const
+{
+  return m_groups;
+}
+
+NetlinkSocketAddress::operator Address (void) const
+{
+  return ConvertTo ();
+}
+
+Address NetlinkSocketAddress::ConvertTo (void) const
+{
+  uint8_t buffer[8];
+
+  buffer[0] = (m_pid >> 24) & 0xff;
+  buffer[1] = (m_pid >> 16) & 0xff;
+  buffer[2] = (m_pid >> 8) & 0xff;
+  buffer[3] = (m_pid >> 0) & 0xff;
+  buffer[4] = (m_groups >> 24) & 0xff;
+  buffer[5] = (m_groups >> 16) & 0xff;
+  buffer[6] = (m_groups >> 8) & 0xff;
+  buffer[7] = (m_groups >> 0) & 0xff;
+
+  return Address (GetType (), buffer, 8);
+}
+
+NetlinkSocketAddress NetlinkSocketAddress::ConvertFrom (const Address &address)
+{
+  NS_ASSERT (IsMatchingType (address));
+
+  NetlinkSocketAddress nl;
+  uint8_t buf[8];
+
+  address.CopyTo (buf);
+
+  nl.m_pid = 0;
+  nl.m_pid |= buf[0];
+  nl.m_pid <<= 8;
+  nl.m_pid |= buf[1];
+  nl.m_pid <<= 8;
+  nl.m_pid |= buf[2];
+  nl.m_pid <<= 8;
+  nl.m_pid |= buf[3];
+
+  nl.m_groups = 0;
+  nl.m_groups |= buf[4];
+  nl.m_groups <<= 8;
+  nl.m_groups |= buf[5];
+  nl.m_groups <<= 8;
+  nl.m_groups |= buf[6];
+  nl.m_groups <<= 8;
+  nl.m_groups |= buf[7];
+
+  return nl;
+}
+
+bool NetlinkSocketAddress::IsMatchingType (const Address &address)
+{
+  return address.IsMatchingType (GetType ());
+}
+
+uint8_t NetlinkSocketAddress::GetType (void)
+{
+  static uint8_t type = Address::Register ();
+  return type;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-socket-address.h	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,71 @@
+/* -*-	Mode:C; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#ifndef NETLINK_SOCKET_ADDRESS_H
+#define NETLINK_SOCKET_ADDRESS_H
+
+#include "ns3/ptr.h"
+#include "ns3/address.h"
+
+namespace ns3 {
+
+class NetlinkSocketAddress
+{
+public:
+  NetlinkSocketAddress (uint32_t pid, uint32_t groups);
+  NetlinkSocketAddress ();
+  ~NetlinkSocketAddress ();
+
+  void SetProcessID (uint32_t pid);
+  void SetGroupsMask (uint32_t mask);
+
+  uint32_t GetProcessID (void) const;
+  uint32_t GetGroupsMask (void) const;
+
+  /**
+  * \returns an Address instance which represents this
+  * NetlinkSocketAddress instance.
+  */
+  operator Address (void) const;
+  /**
+  * \param address the Address instance to convert from.
+  *
+  * Returns an NetlinkSocketAddress which corresponds to the input
+  * Address
+  */
+  static NetlinkSocketAddress ConvertFrom (const Address &address);
+  /**
+  * \returns true if the address matches, false otherwise.
+  */
+  static bool IsMatchingType (const Address &address);
+private:
+  static uint8_t GetType (void);
+  Address ConvertTo (void) const;
+
+  uint32_t m_pid;
+  uint32_t m_groups;
+
+};
+
+
+} // namespace ns3
+
+#endif /* NETLINK_SOCKET_ADDRESS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-socket-factory.cc	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#include "netlink-socket-factory.h"
+#include "netlink-socket.h"
+#include "ns3/node.h"
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (NetlinkSocketFactory);
+
+TypeId 
+NetlinkSocketFactory::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NetlinkSocketFactory")
+    .AddConstructor<NetlinkSocketFactory> ()
+    .SetParent<SocketFactory> ()
+    ;
+  return tid;
+}
+
+NetlinkSocketFactory::NetlinkSocketFactory ()
+{}
+
+Ptr<Socket> NetlinkSocketFactory::CreateSocket (void)
+{
+  Ptr<Node> node = GetObject<Node> ();
+  Ptr<NetlinkSocket> socket = CreateObject<NetlinkSocket> ();
+  socket->SetNode (node);
+  return socket;
+} 
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-socket-factory.h	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,52 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#ifndef NETLINK_SOCKET_FACTORY_H
+#define NETLINK_SOCKET_FACTORY_H
+
+#include "ns3/socket-factory.h"
+
+namespace ns3 {
+
+class Socket;
+
+/**
+ * This can be used as an interface in a node in order for the node to
+ * generate NetlinkSockets.
+ */
+class NetlinkSocketFactory : public SocketFactory
+{
+public:
+  static TypeId GetTypeId (void);
+
+  NetlinkSocketFactory ();
+
+  /**
+   * Creates a NetlinkSocket and returns a pointer to it.
+   *
+   * \return a pointer to the created socket
+   */
+  virtual Ptr<Socket> CreateSocket (void);
+};
+
+} // namespace ns3
+
+#endif /* NETLINK_SOCKET_FACTORY_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-socket.cc	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,1571 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+
+#include "netlink-socket.h"
+#include "netlink-socket-address.h"
+#include "netlink-message.h"
+#include "netlink-message-route.h"
+#include "ns3/log.h"
+#include "ns3/node.h"
+#include "ns3/packet.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/simple-net-device.h"
+#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
+#include <iostream>
+#include <sstream>
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6.h"
+#include "ns3/ipv4-l3-protocol.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-routing-table-entry.h"
+#include "ns3/ipv6-l3-protocol.h"
+#include "ns3/ipv6-interface.h"
+#include "ns3/ipv6-static-routing-helper.h"
+#include "ns3/ipv6-routing-table-entry.h"
+#include "ns3/socket.h"
+#include "ns3/mac48-address.h"
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <errno.h>
+
+NS_LOG_COMPONENT_DEFINE ("NetlinkSocket");
+
+namespace ns3 {
+
+// GroupSockets store the netlinksocket with noero group value
+// it was due to the mulitcast netlink messages.
+class GroupSockets
+{
+public:
+  static uint32_t GetNSockets(void)
+  { 
+    return m_Sockets.size();
+  }
+  static Ptr<NetlinkSocket> GetSocket(uint32_t index)
+  {
+    NS_ASSERT(index < m_Sockets.size());
+    return m_Sockets[index];
+  }
+  static void AddSocket(Ptr<NetlinkSocket>sock)
+  {
+    m_Sockets.push_back(sock);
+  }
+private:
+   /*use a std::vector to store the sockets with nozero group value*/
+  static std::vector<Ptr<NetlinkSocket> >m_Sockets;
+};
+std::vector<Ptr<NetlinkSocket> >GroupSockets::m_Sockets;
+
+NS_OBJECT_ENSURE_REGISTERED (NetlinkSocket);
+
+/*
+Netlink Socket
+*/
+TypeId
+NetlinkSocket::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::NetlinkSocket")
+    .SetParent<Socket> ()
+    .AddConstructor<NetlinkSocket> ()
+    .AddTraceSource ("Drop", "Drop packet due to receive buffer overflow",
+                     MakeTraceSourceAccessor (&NetlinkSocket::m_dropTrace))
+    .AddAttribute ("RcvBufSize",
+                   "NetlinkSocket maximum receive buffer size (bytes)",
+                   UintegerValue (0xffffffffl),
+                   MakeUintegerAccessor (&NetlinkSocket::m_rcvBufSize),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
+                   CallbackValue (),
+                   MakeCallbackAccessor (&NetlinkSocket::m_icmpCallback),
+                   MakeCallbackChecker ())
+    ;
+  return tid;
+}
+
+NetlinkSocket::NetlinkSocket ()
+  : m_shutdownSend (false),
+    m_shutdownRecv (false),
+    m_rxAvailable (0),
+    m_srcPid (0),
+    m_srcGroups (0),
+    m_dstPid (0),
+    m_dstGroups (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_errno = ERROR_NOTERROR;
+}
+NetlinkSocket::~NetlinkSocket ()
+{
+  NS_LOG_FUNCTION (this);
+}
+void 
+NetlinkSocket::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+int
+NetlinkSocket::ErrnoToSimuErrno (void)
+{
+  switch (m_errno)
+    {
+    case Socket::ERROR_ISCONN:
+      return EISCONN;
+    case Socket::ERROR_NOTCONN:
+      return ENOTCONN;
+    case Socket::ERROR_MSGSIZE:
+      return EMSGSIZE;
+    case Socket::ERROR_AGAIN:
+      return EAGAIN;
+    case Socket::ERROR_SHUTDOWN:
+      return ESHUTDOWN;
+    case Socket::ERROR_OPNOTSUPP:
+      return EOPNOTSUPP;
+    case Socket::ERROR_AFNOSUPPORT:
+      return EAFNOSUPPORT;
+    case Socket::ERROR_INVAL:
+      return EINVAL;
+    case Socket::ERROR_BADF:
+      return EBADF;
+    case Socket::ERROR_NOROUTETOHOST:
+      return EHOSTUNREACH;
+    case Socket::ERROR_NODEV:
+      return ENODEV;
+    case Socket::ERROR_ADDRNOTAVAIL:
+      return EADDRNOTAVAIL;
+    case Socket::SOCKET_ERRNO_LAST:
+    case Socket::ERROR_NOTERROR:
+    default:
+      NS_ASSERT (false);
+      return 0; // quiet compiler
+      break;
+    }
+}
+
+void 
+NetlinkSocket::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_node = node;
+}
+
+
+enum Socket::SocketErrno
+NetlinkSocket::GetErrno (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_errno;
+}
+enum Socket::SocketType 
+NetlinkSocket::GetSocketType (void) const
+{
+  return Socket::NS3_SOCK_DGRAM;
+}
+
+Ptr<Node>
+NetlinkSocket::GetNode (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_node;
+}
+
+uint32_t
+NetlinkSocket::GetSrcPid (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_srcPid;
+}
+uint32_t
+NetlinkSocket::GetSrcGroups (void)const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_srcGroups;
+}
+uint32_t
+NetlinkSocket::GetDstPid (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_dstPid;
+}
+uint32_t
+NetlinkSocket::GetDstGroups (void)const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_dstGroups;
+}
+
+int
+NetlinkSocket::Bind (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NetlinkSocketAddress address;
+  return DoBind (address);
+}
+int
+NetlinkSocket::Bind (const Address &address)
+{ 
+  NS_LOG_FUNCTION (this << address);
+
+  if (!NetlinkSocketAddress::IsMatchingType (address))
+    {
+      m_errno = ERROR_INVAL;
+      return -1;
+    }
+  NetlinkSocketAddress ad = NetlinkSocketAddress::ConvertFrom (address);
+  return DoBind (ad);
+}
+int
+NetlinkSocket::DoBind (const NetlinkSocketAddress &address)
+{
+  NS_LOG_FUNCTION (this << address);
+
+  m_srcPid = address.GetProcessID ();
+  m_srcGroups = address.GetGroupsMask ();
+
+  if (m_srcGroups)
+    {
+      GroupSockets::AddSocket(this);
+    } 
+  return 0;
+}
+
+int 
+NetlinkSocket::Listen (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_errno = Socket::ERROR_OPNOTSUPP;
+  return -1;
+}
+
+uint32_t
+NetlinkSocket::GetTxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return 0;
+}
+uint32_t
+NetlinkSocket::GetRxAvailable (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  // We separately maintain this state to avoid walking the queue 
+  // every time this might be called
+  return m_rxAvailable;
+}
+
+int
+NetlinkSocket::ShutdownSend (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_shutdownSend = true;
+  return 0;
+}
+int
+NetlinkSocket::ShutdownRecv (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_shutdownRecv = true;
+  return 0;
+}
+
+int
+NetlinkSocket::Close (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  ShutdownSend();
+  ShutdownRecv();
+  return 0;
+}
+
+int
+NetlinkSocket::Connect (const Address &address)
+{
+  NS_LOG_FUNCTION (this << address);
+  m_errno = Socket::ERROR_OPNOTSUPP;
+  return 0;
+}
+
+Ptr<Packet>
+NetlinkSocket::Recv (uint32_t maxSize, uint32_t flags)
+{
+  NS_LOG_FUNCTION (this << maxSize<< flags);
+  if (m_dataReceiveQueue.empty())
+    {
+      return 0;
+    }
+
+  Ptr<Packet> p = m_dataReceiveQueue.front ();
+  if (p->GetSize () <= maxSize) 
+    {
+      m_dataReceiveQueue.pop ();
+      m_rxAvailable -= p->GetSize ();
+    }
+  else
+    {
+      p = 0; 
+    }
+  return p;
+}
+
+Ptr<Packet>
+NetlinkSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
+{
+  NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
+  Ptr<Packet> packet = Recv (maxSize, flags);
+  if (packet != 0)
+    {
+      SocketAddressTag tag;
+      bool found;
+      found = packet->FindFirstMatchingByteTag (tag);
+      NS_ASSERT (found);
+      fromAddress = tag.GetAddress ();
+    }
+  return packet;
+}
+
+int
+NetlinkSocket::Send (Ptr<Packet> p,uint32_t flags)
+{
+  NS_LOG_FUNCTION (this << p << flags);
+  NetlinkSocketAddress address = NetlinkSocketAddress(m_dstPid, m_dstGroups);
+  return SendTo(p, flags, address);
+}
+
+int
+NetlinkSocket::SendTo (Ptr<Packet> p, uint32_t flags, const Address &toAddress)
+{
+  NS_LOG_FUNCTION (this << p << flags << toAddress);
+  NetlinkSocketAddress ad;
+
+  if (!NetlinkSocketAddress::IsMatchingType (toAddress))
+    {
+      NS_LOG_LOGIC ("ERROR_AFNOSUPPORT");
+      m_errno = ERROR_AFNOSUPPORT;
+      return -1;
+    }
+  ad = NetlinkSocketAddress::ConvertFrom (toAddress);
+  m_dstPid = ad.GetProcessID();
+  m_dstGroups = ad.GetGroupsMask();
+  NS_LOG_INFO ("send netlink message to pid = " << m_dstPid << ", groups = " << m_dstGroups);
+  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Sending netlink message from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ());
+
+  //Ptr<NetlinkSocket>kernel_socket = GetNetlinkSocketByAddress(ad);
+  //kernel_socket->m_receivedData.push_back(p);
+  //kernel_socket->NotifyDataReceived(p);
+
+  //when netlink socket send packet, the first step is to find the dest netlink socket through address
+  //then send the packet to it. For we partly implement the netlink-family, the dest address
+  //is always the kernel(pid = 0), (Actually, there must be one static kernel netlink socket to
+  //receive/handle messages), we do not setup a kernel socket to receive packet.
+  //
+  
+  MultipartNetlinkMessage multipartnlmsg;
+  uint32_t packet_len, remain_len;
+
+  packet_len = p->GetSize ();
+  remain_len = packet_len;
+
+  while (remain_len > NetlinkMessageHeader::GetHeaderSize ())
+    {
+      remain_len -= p->RemoveHeader (multipartnlmsg);
+      NS_ASSERT (remain_len == p->GetSize ());
+
+      //actually, message to kernel contains single one netlink message
+      for (uint32_t i = 0; i < multipartnlmsg.GetNMessages(); i ++)
+        {
+          NetlinkMessage nlmsg = multipartnlmsg.GetMessage (i);
+          if (HandleMessage (nlmsg) < 0)
+            {
+              if (m_errno)
+                {
+                  SendAckMessage (nlmsg, -ErrnoToSimuErrno ());
+                }
+            }
+          else if (NetlinkMessage::IsMessageFlagsAck (nlmsg.GetHeader ().GetMsgFlags ()))
+            {
+              SendAckMessage (nlmsg, 0);
+            }
+        }
+    }
+
+  NotifyDataSent (packet_len);
+  NS_LOG_INFO ("netlink socket kernel error " << -m_errno);
+  return packet_len;
+}
+
+int
+NetlinkSocket::GetSockName (Address &address) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NetlinkSocketAddress ad;
+
+  ad.SetProcessID (GetSrcPid ());
+  ad.SetGroupsMask (GetSrcGroups ());
+  address = ad;
+  return 0;
+}
+int
+NetlinkSocket::GetPeerName (Address &address) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  // XXX
+  NS_ASSERT (false);
+  return -1;
+}
+bool 
+NetlinkSocket::SetAllowBroadcast (bool allowBroadcast)
+{
+  NS_ASSERT (false);
+  return false;
+}
+bool 
+NetlinkSocket::GetAllowBroadcast () const
+{
+  NS_ASSERT (false);
+  return false;
+}
+
+
+void
+NetlinkSocket::ForwardUp (Ptr<Packet> packet, NetlinkSocketAddress &address)
+{
+  NS_LOG_FUNCTION (this << packet << address);
+
+  if (m_shutdownRecv)
+    {
+      return;
+    }
+  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
+    {
+      SocketAddressTag tag;
+      tag.SetAddress (address);
+      packet->AddByteTag (tag);
+      m_dataReceiveQueue.push (packet);
+      m_rxAvailable += packet->GetSize ();
+      NotifyDataRecv ();
+    }
+  else
+    {
+      NS_LOG_WARN ("No receive buffer space available.  Drop.");
+      m_dropTrace (packet);
+    }
+}
+
+int32_t
+NetlinkSocket::SendMessageUnicast (const MultipartNetlinkMessage &nlmsg, uint32_t pid, int32_t nonblock)
+{
+  NS_LOG_FUNCTION (this << pid << nonblock);
+  //here we send message instantly
+  Ptr<Packet> p = Create<Packet> ();
+  p->AddHeader (nlmsg);
+
+  NetlinkSocketAddress address;
+  address.SetProcessID (pid);
+
+  //send packet to user space
+  ForwardUp (p, address);
+  return 0;
+}
+int32_t
+NetlinkSocket::SendMessageBroadcast (const MultipartNetlinkMessage &nlmsg, 
+                                     uint32_t pid, 
+                                     uint32_t group,
+                                     Ptr<Node> node)
+{
+  NS_LOG_FUNCTION ("SendMessageBroadcast" << pid << group);
+  //fisrt find the dest netlink socket through group value, then attach this nlmsg to its recv-queue
+  for (uint32_t i = 0; i < GroupSockets::GetNSockets (); i ++)
+    {
+      Ptr<NetlinkSocket> nlsock = GroupSockets::GetSocket (i);
+
+      if ((nlsock->GetSrcGroups () & group) &&
+          (nlsock->GetSrcPid () != pid) &&
+          node == nlsock->GetNode ())
+        {
+          //here we send message instantly
+          Ptr<Packet> p = Create<Packet> ();
+          p->AddHeader (nlmsg);
+
+          NetlinkSocketAddress address;
+          address.SetProcessID (nlsock->GetSrcPid());
+          address.SetGroupsMask (group);
+
+          //send packet to user space
+          nlsock->ForwardUp (p, address);
+        }
+    }
+  return 0;
+}
+void
+NetlinkSocket::SendAckMessage (const NetlinkMessage&nlmsg, int32_t err)
+{
+  NS_LOG_FUNCTION (this << err);
+  NetlinkMessageHeader rep;
+  NetlinkMessage ackmsg;
+  NetlinkMessageError errmsg;
+
+  rep.SetMsgPid (nlmsg.GetHeader ().GetMsgPid ());
+  rep.SetMsgSeq (nlmsg.GetHeader ().GetMsgSeq ());
+  rep.SetMsgType (NETLINK_MSG_ERROR);
+  rep.SetMsgFlags (0);
+
+  errmsg.SetError (err);
+  //kernel send the whole nlmsg back if error != 0, here we just send the header back
+  errmsg.SetMsg (nlmsg.GetHeader ());
+
+  //then send errmsg back to user space
+  ackmsg.SetHeader (rep);
+  ackmsg.SetErrorMessage (errmsg);
+
+  SendMessageUnicast (ackmsg, rep.GetMsgPid (), 1);
+}
+
+int32_t
+NetlinkSocket::HandleMessage (const NetlinkMessage&nlmsg)
+{
+  NS_LOG_FUNCTION (this);
+  uint16_t type = nlmsg.GetMsgType ();
+  NetlinkMessageHeader nhr = nlmsg.GetHeader ();
+
+  if (nhr.GetMsgLen () < NetlinkMessageHeader::GetHeaderSize ())
+    {
+      m_errno = ERROR_INVAL;
+      return -1;
+    }
+
+  if (NetlinkMessage::IsMessageNetlinkControl (type))
+    {
+      NS_LOG_INFO ("netlink control message type not parsed in kernel");
+      return 0;
+    }
+  else if (NetlinkMessage::IsMessageNetlinkRoute (type))
+    {
+      return HandleNetlinkRouteMessage (nlmsg);
+    }
+  else
+    {
+      NS_LOG_INFO ("netlink message type not parsed in kernel");
+      m_errno = ERROR_INVAL;
+      return -1;
+    }  
+}
+
+int32_t
+NetlinkSocket::HandleNetlinkRouteMessage (const NetlinkMessage &nlmsg)
+{
+  NS_LOG_FUNCTION (this);
+  uint8_t family;
+  int16_t type;
+  int32_t err;
+
+  /* Only requests are handled by kernel now */
+  if (!NetlinkMessage::IsMessageFlagsRequest (nlmsg.GetHeader ().GetMsgFlags ()))
+    return 0;
+
+  type = nlmsg.GetMsgType ();
+
+  /* A control message: ignore them */
+  if (NetlinkMessage::IsMessageNetlinkControl (type))
+    {
+      return 0;
+    }
+  else if (NetlinkMessage::IsMessageNetlinkRoute (type))
+    {
+      /* All the messages must have at least 1 byte length */
+      if (nlmsg.GetPayloadSize () < 1)
+        return 0;
+
+      family = nlmsg.GetFamily ();
+      /*here we do not deal with different family, default for AF_NET*/
+      NS_ASSERT(family == AF_INET || family == AF_UNSPEC || family == AF_PACKET || family == AF_INET6);  
+
+      /*for GET*** message, dump it to userspace*/
+      if (NetlinkMessage::IsMessageTypeGet (type) && 
+          NetlinkMessage::IsMessageFlagsDump (nlmsg.GetHeader ().GetMsgFlags ())) 
+        {
+          DumpNetlinkRouteMessage (nlmsg, type, family);
+          return -1;
+        }
+
+      /* other types of messages*/
+      return DoNetlinkRouteMessage (nlmsg, type, family);
+    }
+  else/* Unknown message: reply with EINVAL */
+    {
+      err = ERROR_INVAL;
+      return -1;
+    } 
+}
+
+int32_t
+NetlinkSocket::DumpNetlinkRouteMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << type << family);
+
+  NS_ASSERT (type == NETLINK_RTM_GETADDR || type == NETLINK_RTM_GETROUTE || type == NETLINK_RTM_GETLINK);
+
+  MultipartNetlinkMessage nlmsg_dump;
+  NetlinkMessageHeader nhr = nlmsg.GetHeader ();
+  int32_t err;
+
+  if (type == NETLINK_RTM_GETADDR)
+    {
+      nlmsg_dump = BuildInterfaceAddressDumpMessage (m_srcPid, nhr.GetMsgSeq(), family);
+    }
+  else if (type == NETLINK_RTM_GETLINK)
+    {
+      nlmsg_dump = BuildInterfaceInfoDumpMessage (m_srcPid, nhr.GetMsgSeq(), family);      
+    }
+  else if (type == NETLINK_RTM_GETROUTE)
+    {
+      nlmsg_dump = BuildRouteDumpMessage (m_srcPid, nhr.GetMsgSeq(), family);
+    }
+  else
+    {
+      m_errno = ERROR_INVAL;
+      return -1;
+    }
+
+  //then append netlink message with type NLMSG_DONE
+  NetlinkMessage nlmsg_done;
+  NetlinkMessageHeader nhr2 = NetlinkMessageHeader (NETLINK_MSG_DONE, NETLINK_MSG_F_MULTI, 
+                                                   nlmsg.GetHeader ().GetMsgSeq (), m_srcPid);
+  nlmsg_done.SetHeader (nhr2);
+  //kernel append nlmsg_dump size to it, here we omit it
+  nlmsg_dump.AppendMessage (nlmsg_done);
+
+  err = SendMessageUnicast (nlmsg_dump, m_srcPid, 1);
+  return err;
+}
+
+/*here only for ADD/DEL/GET*** types*/
+int32_t
+NetlinkSocket::DoNetlinkRouteMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << type <<family);
+  int32_t err;
+
+  if (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR)
+    {      
+      err = DoInterfaceAddressMessage (nlmsg, type, family);
+    }
+  else if (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE || type == NETLINK_RTM_GETROUTE)
+    {     
+      err = DoRouteMessage (nlmsg, type, family);
+    }
+  else if (type == NETLINK_RTM_GETLINK || type == NETLINK_RTM_SETLINK)
+    {     
+      err = DoInterfaceInfoMessage (nlmsg, type, family);
+    }
+  else
+    {
+      NS_LOG_LOGIC ("netlink message:type( " << type << ") not processed by ns3 now." );
+      m_errno = ERROR_INVAL;
+      err = -1;
+    } 
+  
+  return err;
+}
+
+MultipartNetlinkMessage
+NetlinkSocket::BuildInterfaceAddressDumpMessage (uint32_t pid, uint32_t seq, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << pid << seq <<family);
+  MultipartNetlinkMessage nlmsg_dump;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i ++)
+    {
+      if (!ipv4->IsUp (i))
+        continue;
+
+      Ipv4Address addri = ipv4->GetAddress (i, 0).GetLocal ();
+      Ipv4Mask maski = ipv4->GetAddress (i, 0).GetMask ();
+      Ipv4Address bcast = ipv4->GetAddress (i, 0).GetBroadcast ();
+
+      //here get the address mask length
+      uint32_t mask = maski.Get ();
+      uint8_t mask_len = 0;
+      while (mask)
+        {
+          mask = mask << 1;
+          mask_len ++;
+        }
+      
+      //next fill the message body
+      NetlinkMessage nlmsg_ifa;
+      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWADDR, NETLINK_MSG_F_MULTI, seq, pid);
+      InterfaceAddressMessage ifamsg;
+
+      ifamsg.SetInterfaceIndex (i);
+      ifamsg.SetFamily (AF_INET);//default AF_INET      
+      ifamsg.SetLength (mask_len);
+      ifamsg.SetFlags (0);
+      ifamsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
+
+      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LOCAL,    ADDRESS, addri));
+      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ADDRESS,  ADDRESS, addri));
+      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_BROADCAST,ADDRESS, bcast));
+      //      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LABEL,    STRING,  "ns3-ifaddr"));//not used in ns3
+      //ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ANYCAST,  ADDRESS, Ipv4Address("0.0.0.0")));//not used in ns3
+      //XXXother attributes not used by ns3
+
+      nlmsg_ifa.SetHeader(nhr);
+      nlmsg_ifa.SetInterfaceAddressMessage (ifamsg);
+      nlmsg_dump.AppendMessage (nlmsg_ifa);
+    }
+
+  // For IPv6
+  Ptr<Ipv6>ipv6 = m_node->GetObject<Ipv6> ();
+
+  for (uint32_t i = 0; i < ipv6->GetNInterfaces(); i ++)
+    {
+      if (!ipv6->IsUp (i))
+        continue;
+
+      for (uint32_t j = 0; j < ipv6->GetNAddresses(i); j ++)
+        {
+          Ipv6Address addri = ipv6->GetAddress (i, j).GetAddress();
+          Ipv6Prefix prefix = ipv6->GetAddress (i, j).GetPrefix ();
+
+          //here get the address mask length
+          uint8_t mask_len = prefix.GetPrefixLength();
+
+          //loopback address's prefix is wrong... FIXME
+          if (addri.IsEqual(Ipv6Address::GetLoopback()))
+            mask_len = 128;
+      
+          //next fill the message body
+          NetlinkMessage nlmsg_ifa;
+          NetlinkMessageHeader nhr = NetlinkMessageHeader(NETLINK_RTM_NEWADDR, NETLINK_MSG_F_MULTI, seq, pid);
+          InterfaceAddressMessage ifamsg;       
+
+          ifamsg.SetInterfaceIndex(i);
+          ifamsg.SetFamily(AF_INET6);
+          ifamsg.SetFlags(0);
+
+
+          if (addri.IsLinkLocal())
+            {
+              ifamsg.SetLength(64);
+              ifamsg.SetScope (RouteMessage::RT_SCOPE_LINK);
+            }
+          else
+            {
+              ifamsg.SetLength(mask_len);
+              ifamsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
+            }
+
+
+          ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LOCAL,    ADDRESS, addri));
+          ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ADDRESS,  ADDRESS, addri));
+          //XXXother attributes not used by ns3
+
+          nlmsg_ifa.SetHeader(nhr);
+          nlmsg_ifa.SetInterfaceAddressMessage (ifamsg);
+          nlmsg_dump.AppendMessage (nlmsg_ifa);
+        }
+    }
+  return nlmsg_dump;
+}
+MultipartNetlinkMessage
+NetlinkSocket::BuildInterfaceInfoDumpMessage (uint32_t pid, uint32_t seq, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << pid << seq <<family);
+  MultipartNetlinkMessage nlmsg_dump;
+  for (uint32_t i = 0; i < m_node->GetNDevices (); i ++)
+    {
+      Ptr<NetDevice> dev = m_node->GetDevice (i);
+      Address mac;
+      Address bcast;
+      uint32_t mtu;
+      uint32_t flags = 0;
+
+      mac = dev->GetAddress ();
+      bcast = dev->GetBroadcast ();
+      mtu = (uint32_t)dev->GetMtu ();
+
+      if (dev->IsLinkUp ())
+        {
+          flags |= IFF_RUNNING;
+          flags |= IFF_UP;
+        }
+      if (dev->IsBroadcast ())
+        {
+          flags |= IFF_BROADCAST;
+        }
+      if (dev->IsMulticast ())
+        {
+          flags |= IFF_MULTICAST;
+        }
+
+      NetlinkMessage nlmsg_ifinfo;
+      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWLINK, NETLINK_MSG_F_MULTI, seq, pid);
+      InterfaceInfoMessage ifinfomsg;     
+
+      ifinfomsg.SetFamily(0);      // AF_UNSPEC
+      ifinfomsg.SetDeviceType (0); // not clear
+      ifinfomsg.SetInterfaceIndex (i);
+      ifinfomsg.SetDeviceFlags (flags); // not clear
+      ifinfomsg.SetChangeMask (0xffffffff);
+
+      // the ns3 device have no  name, here we set "ns3-device i" for test
+      std::stringstream ss;
+      ss <<  "ns3-device" << i;
+
+      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_IFNAME,    STRING,  ss.str()));
+      //not used in ns3
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_TXQLEN,    U32,     0));
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_WEIGHT,    U32,     0));
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_OPERSTATE, U8,      0));
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_LINKMODE,  U8,      0));
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_MAP,       UNSPEC,  0));
+      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_ADDRESS,   ADDRESS, mac));
+      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_BROADCAST, ADDRESS, bcast));
+      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_MTU,       U32,     mtu));
+      ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_LINK,      U32,     i));
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_QDISC,     STRING,  ""));
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_MASTER,    U32,     0));
+      //ifinfomsg.AppendAttribute (NetlinkAttribute (InterfaceInfoMessage::IFL_A_STATS,     UNSPEC,  0));
+
+      nlmsg_ifinfo.SetHeader (nhr);
+      nlmsg_ifinfo.SetInterfaceInfoMessage (ifinfomsg);
+      nlmsg_dump.AppendMessage (nlmsg_ifinfo);
+    }
+  return nlmsg_dump;
+}
+MultipartNetlinkMessage
+NetlinkSocket::BuildRouteDumpMessage (uint32_t pid, uint32_t seq, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << pid << seq <<family);
+  MultipartNetlinkMessage nlmsg_dump;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  // We only care about staticRouting for netlink support
+  Ipv4StaticRoutingHelper routingHelper;
+  Ptr<Ipv4StaticRouting> ipv4Static = routingHelper.GetStaticRouting (ipv4);
+  for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); i ++)
+    {
+      NetlinkMessage nlmsg_rt;
+      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, NETLINK_MSG_F_MULTI, seq, pid);
+      RouteMessage rtmsg;
+      Ipv4RoutingTableEntry route = ipv4Static->GetRoute (i);
+
+      rtmsg.SetFamily (AF_INET);
+      rtmsg.SetDstLength (32);
+      rtmsg.SetSrcLength (0);
+      rtmsg.SetTos (0);//not clear
+      rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
+      rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
+      rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
+      rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
+
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
+      // ns3 use local address as the route src address
+      //      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, route.GetSource()));
+      //      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, route.GetSource()));//not used in ns3
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface ()));
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface ()));      
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway ()));
+
+      nlmsg_rt.SetHeader (nhr);
+      nlmsg_rt.SetRouteMessage (rtmsg);
+      nlmsg_dump.AppendMessage (nlmsg_rt);
+    }
+
+  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
+  // We only care about staticRouting for netlink support
+  Ipv6StaticRoutingHelper routingHelper6;
+  Ptr<Ipv6StaticRouting> ipv6Static = routingHelper6.GetStaticRouting (ipv6);
+  for (uint32_t i = 0; i < ipv6Static->GetNRoutes (); i ++)
+    {
+      NetlinkMessage nlmsg_rt;
+      NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, NETLINK_MSG_F_MULTI, seq, pid);
+      RouteMessage rtmsg;
+      Ipv6RoutingTableEntry route = ipv6Static->GetRoute (i);
+
+      rtmsg.SetFamily (AF_INET6);
+      rtmsg.SetDstLength (128);
+      rtmsg.SetSrcLength (0);
+      rtmsg.SetTos (0);//not clear
+      rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
+      rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
+      rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
+      rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
+
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
+      //ns3 use local address as the route src address
+      // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, 
+      //                                          ipv6->GetSourceAddress(route.GetDest ())));
+      // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, 
+      //                                          ipv6->GetSourceAddress(route.GetDest ())));
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface()));
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface()));      
+      rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway()));
+
+      nlmsg_rt.SetHeader (nhr);
+      nlmsg_rt.SetRouteMessage (rtmsg);
+      nlmsg_dump.AppendMessage (nlmsg_rt);
+    }
+
+  return nlmsg_dump;
+}
+
+int32_t
+NetlinkSocket::DoInterfaceAddressMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << type << family);
+  NS_ASSERT (type == NETLINK_RTM_NEWADDR || type == NETLINK_RTM_DELADDR);
+
+  // XXX
+  NS_ASSERT_MSG (false, "Not implemented yet (RTM_NEWADDR/RTM_DELADDR)");
+
+  InterfaceAddressMessage ifamsg = nlmsg.GetInterfaceAddressMessage ();
+  Ipv4Address addri, addr_local, bcast;
+  NetlinkAttribute attr_local;
+  uint32_t index = ifamsg.GetInterfaceIndex ();
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+  int flag4 = 0, flag6 = 0;
+
+  if (type == NETLINK_RTM_NEWADDR)
+    {
+      //when adding an interface address, it should check the input arguments
+      //prefix-len and local address attribute
+      if (ifamsg.GetLength () > 32 || 
+          ifamsg.GetAttributeByType (attr_local, InterfaceAddressMessage::IF_A_LOCAL) == false)
+        {
+          m_errno = ERROR_INVAL;
+          return -1;
+        }
+    }  
+
+  //get necessary information for add/del, many attributes we not used
+  for (uint32_t i = 0; i < ifamsg.GetNNetlinkAttribute (); i ++)
+    {
+      NetlinkAttribute attr = ifamsg.GetNetlinkAttribute (i);
+      uint32_t attr_type = attr.GetAttrType ();
+
+      switch(attr_type)
+        {
+        case InterfaceAddressMessage::IF_A_ADDRESS:
+          addri = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
+          break;
+        case InterfaceAddressMessage::IF_A_BROADCAST:
+          bcast = Ipv4Address::ConvertFrom(attr.GetAttrPayload ().GetAddress ());
+          break;
+        case InterfaceAddressMessage::IF_A_LOCAL:
+          addr_local = Ipv4Address::ConvertFrom(attr.GetAttrPayload ().GetAddress ());
+          break;
+        case InterfaceAddressMessage::IF_A_LABEL:
+        case InterfaceAddressMessage::IF_A_ANYCAST:
+          break;
+        }
+    }
+
+  if (type == NETLINK_RTM_NEWADDR)
+    {
+      //when adding an interface address by index, if the indexed interface was not exist,
+      //create an new NetDevice with an new index and set the address
+      //otherwise set the indexed interface directly
+      if (index >= ipv4->GetNInterfaces ())
+        {          
+          Ptr<SimpleNetDevice> dev;
+          dev = CreateObject<SimpleNetDevice> ();
+          dev ->SetAddress (Mac48Address::Allocate ());
+          m_node->AddDevice (dev);
+
+          uint32_t netdev_idx = ipv4->AddInterface (dev);
+          // FIXME!
+          Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (addri, Ipv4Mask ());
+          ipv4->AddAddress (netdev_idx, ipv4Addr);
+          ipv4->SetUp (netdev_idx);
+          NS_LOG_INFO ("Add an interface address at index "<< netdev_idx << "but not the ifamsg input" << index);
+        }
+      else
+        {
+          Ipv4InterfaceAddress ipv4Addr = Ipv4InterfaceAddress (addri, Ipv4Mask ());
+          ipv4->AddAddress (index, ipv4Addr);
+          if (!ipv4->IsUp (index))
+            ipv4->SetUp (index);
+        }    
+      flag4 = 1;
+    }
+  else//type == NETLINK_RTM_DELADDR
+    {
+      //when delete an interface address by index, if the indexed interface  was not exist
+      //return an error EINVAL, otherwise set down the interface which has the addri
+      if (index >= ipv4->GetNInterfaces ())
+        {
+          m_errno = ERROR_NODEV;
+          return -1;
+        }
+      else
+        {
+          for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i ++)
+            {
+              Ipv4Address ad = ipv4->GetAddress (i, 0).GetLocal ();
+              if (ad == addri && ipv4->IsUp (i))
+                {
+                  ipv4->SetDown (i);
+                  break;
+                }
+              if (i == ipv4->GetNInterfaces () - 1)
+                {
+                  m_errno = ERROR_ADDRNOTAVAIL;
+                  return -1;
+                }
+            }
+          flag4 = 1;
+        }      
+    }
+  
+  //then send an broadcast message, let all user know this operation happened
+  NetlinkMessage nlmsg_broadcast = nlmsg;
+  NetlinkMessageHeader nhr;
+  nhr.SetMsgLen (nlmsg.GetHeader ().GetMsgLen ());
+  nhr.SetMsgType (nlmsg.GetHeader ().GetMsgType ());
+  nlmsg_broadcast.SetHeader (nhr);
+  if (flag4)
+    {
+      SendMessageBroadcast (nlmsg_broadcast, 0, NETLINK_RTM_GRP_IPV4_IFADDR, GetNode ());
+    }
+  else if (flag6)
+    {
+      SendMessageBroadcast (nlmsg_broadcast, 0, RTMGRP_IPV6_IFADDR, GetNode ());
+    }
+
+  return 0;
+}
+
+int32_t
+NetlinkSocket::DoInterfaceInfoMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << type << family);
+  NS_ASSERT (type == NETLINK_RTM_GETLINK || type == NETLINK_RTM_SETLINK);
+  InterfaceInfoMessage ifinfomsg = nlmsg.GetInterfaceInfoMessage ();
+  // XXX
+  NS_ASSERT_MSG (false, "Not implemented yet (RTM_GETLINK/RTM_SETLINK)");
+  return -1;
+}
+
+Address
+NetlinkSocket::ConvertFrom (uint8_t family, const Address &address)
+{
+  Address retval;
+  if (family == AF_INET)
+    {
+      retval = Ipv4Address::ConvertFrom (address);
+    }
+  else if (family == AF_INET6)
+    {
+      retval = Ipv6Address::ConvertFrom (address);
+    }
+  return retval;
+}
+
+int32_t
+NetlinkSocket::DoRouteMessage (const NetlinkMessage &nlmsg, uint16_t type, uint8_t family)
+{
+  NS_LOG_FUNCTION (this << type << family);
+  NS_ASSERT (type == NETLINK_RTM_NEWROUTE || type == NETLINK_RTM_DELROUTE ||type == NETLINK_RTM_GETROUTE);
+
+  RouteMessage rtmsg = nlmsg.GetRouteMessage ();
+  Ipv4Address src, dest, gateway;
+  Ipv6Address src6, dest6, gateway6;
+  uint32_t index = 0;
+  int attr_flags[RouteMessage::RT_A_MAX] = {0};
+  uint8_t dstlen = rtmsg.GetDstLength ();
+
+  //get necessary information for add/del, many attributes we not used
+  for (uint32_t i = 0; i < rtmsg.GetNNetlinkAttribute (); i ++)
+    {
+      NetlinkAttribute attr = rtmsg.GetNetlinkAttribute (i);
+      uint32_t attr_type = attr.GetAttrType ();
+      attr_flags[attr_type] = 1;
+
+      switch(attr_type)
+        {
+        case RouteMessage::RT_A_DST:
+          if (family == AF_INET)
+            {
+              dest = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
+            }
+          else if (family == AF_INET6)
+            {
+              dest6 = Ipv6Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
+            }
+          break;
+        case RouteMessage::RT_A_SRC:
+          if (family == AF_INET)
+            {
+              src = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
+            }
+          else if (family == AF_INET6)
+            {
+              src6 = Ipv6Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
+            }
+          break;
+        case RouteMessage::RT_A_OIF:
+          index = attr.GetAttrPayload ().GetU32 ();
+          break;
+        case RouteMessage::RT_A_GATEWAY:
+          if (family == AF_INET)
+            {
+              gateway = Ipv4Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
+            }
+          else if (family == AF_INET6)
+            {
+              gateway6 = Ipv6Address::ConvertFrom (attr.GetAttrPayload ().GetAddress ());
+            }
+          break;
+        case RouteMessage::RT_A_IIF:
+        case RouteMessage::RT_A_PRIORITY:
+        case RouteMessage::RT_A_PREFSRC:
+        case RouteMessage::RT_A_METRICS:
+        case RouteMessage::RT_A_MULTIPATH:
+        case RouteMessage::RT_A_PROTOINFO:
+        case RouteMessage::RT_A_FLOW:
+        case RouteMessage::RT_A_CACHEINFO:
+        case RouteMessage::RT_A_SESSION:
+        case RouteMessage::RT_A_MP_ALGO:
+        case RouteMessage::RT_A_TABLE:
+          NS_LOG_INFO("route attribute not used by ns3" << attr_type);
+          //not used by ns3
+          break;
+        }
+    }
+
+  // Sigh....
+  Ptr<Ipv4>ipv4 = m_node->GetObject<Ipv4> ();
+  Ipv4StaticRoutingHelper routingHelper;
+  Ptr<Ipv4StaticRouting> ipv4Static = routingHelper.GetStaticRouting (ipv4);
+
+  Ptr<Ipv6>ipv6 = m_node->GetObject<Ipv6> ();
+  Ipv6StaticRoutingHelper routingHelper6;
+  Ptr<Ipv6StaticRouting> ipv6Static = routingHelper6.GetStaticRouting (ipv6);
+
+  NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << " Route message, type: " << type << "; from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
+      << " to " << dest<< " through " << gateway);
+
+  if (type == NETLINK_RTM_NEWROUTE)
+    {
+      //ns3 add a route entry only depends on 2 or 3 attribute
+      //other route msg attibute were ignored
+      if (attr_flags[RouteMessage::RT_A_DST])
+        {
+          if (family == AF_INET)
+            {
+              if (!attr_flags[RouteMessage::RT_A_OIF])
+                {
+                  bool found = 0;
+                  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
+                    {
+                      for (uint32_t j = 0; j < ipv4->GetNAddresses (i); j++)
+                        {
+                          if ((attr_flags[RouteMessage::RT_A_GATEWAY]))
+                            {
+                              Ipv4Mask mask = ipv4->GetAddress (i, j).GetMask ();
+                              if (mask.IsMatch (ipv4->GetAddress (i, j).GetLocal (), gateway))
+                                {
+                                  index = i;
+                                  found = true;
+                                  break;
+                                }
+                            }
+                          if (found) break;
+                        }
+                    }
+                  if (!found)
+                    {
+                      NS_LOG_DEBUG ("No suitable interface to add an route entry");
+                      m_errno = ERROR_ADDRNOTAVAIL;
+                      return -1;
+                    }
+                }
+            if (dstlen == 32)
+              {
+                int exist_flag = 0;
+                for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); ++i)
+                  {
+                    Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
+                    if (dest == rt.GetDest ())
+                      {
+                        exist_flag = 1;
+                      }
+                  }
+
+                if (exist_flag)
+                  { //route to dest already exists
+                    int delete_flag = 0;
+                    if (nlmsg.GetHeader ().GetMsgFlags () & NETLINK_MSG_F_REPLACE)
+                      {
+                        for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); ++i)
+                          {
+                            Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
+                            if (dest == rt.GetDest ())
+                              {
+                                ipv4Static->RemoveRoute (i);
+                                NS_LOG_DEBUG ("Route from  " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << " to "
+                                    << dest << " through " << gateway << " removed");
+                                delete_flag = 1;
+                              }
+                          }
+
+                        if (!delete_flag)
+                          {
+                             NS_LOG_INFO ("no route entry removed by dest address in new route sector " << dest);
+                             m_errno = ERROR_INVAL;
+                             return -1;
+                           }
+                      }
+                    else
+                      {
+                        NS_LOG_DEBUG ("Route exists but overwriting declined!");
+                      }
+                    if ((attr_flags[RouteMessage::RT_A_GATEWAY]))
+                      {
+                        NS_LOG_DEBUG (Simulator::Now().GetSeconds() << "Overwrite route from "
+                            << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << " to " << dest<< " through " << gateway << " with index" << index);
+                        ipv4Static->AddHostRouteTo (dest, gateway, index);
+                      }
+                    else
+                      {
+                        NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Overwrite route from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
+                            << " to " << dest<< " through " << "self" << " with index" << index);
+                        ipv4Static->AddHostRouteTo (dest, index);
+                      }
+                }
+                else
+                  { //route to dest doesn't exist
+                    if (nlmsg.GetHeader ().GetMsgFlags () & NETLINK_MSG_F_CREATE)
+                      {
+                        if (attr_flags[RouteMessage::RT_A_GATEWAY])
+                          {
+                            NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Add new route from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
+                                << " to " << dest<< " through " << gateway << " with index" << index);
+                            ipv4Static->AddHostRouteTo (dest, gateway, index);
+                          }
+                        else
+                          {
+                            NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Add new route from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
+                                << " to " << dest<< " through " << "self" << " with index" << index);
+                            ipv4Static->AddHostRouteTo (dest, index);
+                          }
+                      }
+                    else
+                      {
+                        NS_LOG_ERROR ("Route doesn't exist but writing declined!");
+                      }
+                  }
+
+                NS_LOG_DEBUG ("=After change attempt=");
+                //Dump of table
+                NS_LOG_DEBUG (m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << ":");
+                for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); ++i)
+                  {
+                    Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
+                    NS_LOG_DEBUG (rt.GetDest () << " through " << rt.GetGateway ());
+                  }
+                NS_LOG_DEBUG ("= = = = = = = = = = =");
+              }
+            else // dstlen != 32
+              {
+                if (attr_flags[RouteMessage::RT_A_GATEWAY])
+                  {
+                    ipv4Static->AddNetworkRouteTo (dest, Ipv4Mask (~(1<<(32 - dstlen))+1), gateway, index);
+                  }
+                else
+                  {
+                    ipv4Static->AddNetworkRouteTo (dest, Ipv4Mask (~(1<<(32 - dstlen))+1), index);
+                  }
+              }
+          }
+          else if (family == AF_INET6)
+            {
+            if (!attr_flags[RouteMessage::RT_A_OIF])
+              {
+#ifdef FIXME
+              if (ipv6->GetIfIndexForDestination (gateway6, index) == false)
+                {
+                  NS_LOG_INFO ("No suitable interface to add an route entry");
+                  m_errno = ERROR_ADDRNOTAVAIL;
+                  return -1;
+                }
+#endif
+              }
+
+            Ipv6Prefix pref (dstlen);
+            if (attr_flags[RouteMessage::RT_A_GATEWAY])
+              {
+                ipv6Static->AddNetworkRouteTo (dest6, pref, gateway6, index);
+              }
+            else
+              {
+                ipv6Static->AddNetworkRouteTo (dest6, pref, Ipv6Address("::"), index);
+              }
+            }
+          }
+        else
+          {
+            NS_LOG_INFO("too few attributes to add an route entry");
+            m_errno = ERROR_INVAL;
+            return -1;
+          }
+    }
+  else if (type == NETLINK_RTM_DELROUTE)
+    {
+      NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "Route delete request from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal ()
+          << " to " << dest<< " through " << gateway);
+      if (attr_flags[RouteMessage::RT_A_DST])
+        {
+          int delete_flag = 0;
+
+          if (family == AF_INET)
+            {
+              for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); i ++)
+                {
+                Ipv4RoutingTableEntry rt = ipv4Static->GetRoute (i);
+                if (gateway == rt.GetGateway () && dest == rt.GetDest ())
+                  {
+                    ipv4Static->RemoveRoute (i);
+                    delete_flag = 1;
+                  }
+                }
+            }
+          else if (family == AF_INET6)
+            {
+              for (uint32_t i = 0; i < ipv6Static->GetNRoutes (); i ++)
+                {
+                Ipv6RoutingTableEntry rt = ipv6Static->GetRoute (i);
+                if (gateway6 == rt.GetGateway () && dest6 == rt.GetDest ())
+                  {
+                    ipv6Static->RemoveRoute (i);
+                    delete_flag = 1;
+                  }
+                }
+            }
+
+          if (!delete_flag)
+            {
+              NS_LOG_INFO ("no route entry removed by dest address " << dest);
+              m_errno = ERROR_INVAL;
+              return -1;
+            }
+        }
+      else
+        {
+          NS_LOG_INFO ("too few attributes to add an route entry");
+          m_errno = ERROR_INVAL;
+          return -1;    
+        }
+    }
+  else// type == NETLINK_RTM_GETROUTE
+    {
+      NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << "GetRoute "<< "from " << m_node->GetObject<Ipv4> ()->GetAddress (1, 0).GetLocal () << " to " << dest);
+      if (!attr_flags[RouteMessage::RT_A_DST])
+        {
+          NS_LOG_INFO ("too few attributes to get an route entry");
+          m_errno = ERROR_INVAL;
+          return -1;
+        }
+      
+      int get_flag = 0;
+      if (family == AF_INET)
+        {
+          for (uint32_t i = 0; i < ipv4Static->GetNRoutes (); i ++)
+            {
+              Ipv4RoutingTableEntry route = ipv4Static->GetRoute (i);
+              //find the route entry with same dest address and send unicast to user space
+              if (dest.IsEqual (route.GetDest ()))
+                {
+                  //                Ptr<Ipv4>ipv4 = m_node->GetObject<Ipv4> ();
+                  NetlinkMessage nlmsg_route;
+                  NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, 0, 
+                                                                   nlmsg.GetHeader ().GetMsgSeq (), m_srcPid);
+                  RouteMessage rtmsg;
+
+                  //fill rtmsg and attributes
+                  rtmsg.SetFamily (AF_INET);
+                  rtmsg.SetDstLength (32);
+                  rtmsg.SetSrcLength (0);
+                  rtmsg.SetTos (0);//not clear
+                  rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
+                  rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
+                  rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
+                  rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
+
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
+                  //ns3 use local address as the route src address
+                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, ipv4->GetSourceAddress(route.GetDest ())));
+                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, ipv4->GetSourceAddress(route.GetDest ())));
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface ()));
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface ()));
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway ()));
+
+                  //fill an netlink message body
+                  nlmsg_route.SetHeader (nhr);
+                  nlmsg_route.SetRouteMessage (rtmsg);
+                  
+                  SendMessageUnicast (nlmsg_route, m_srcPid, 1);
+                  get_flag = 1;
+                }
+            }
+        }
+      else if (family == AF_INET6)
+        {
+          for (uint32_t i = 0; i < ipv6Static->GetNRoutes(); i ++)
+            {
+              Ipv6RoutingTableEntry route = ipv6Static->GetRoute (i);
+              //find the route entry with same dest address and send unicast to user space
+              if (dest6.IsEqual (route.GetDest ()))
+                {
+                  NetlinkMessage nlmsg_route;
+                  NetlinkMessageHeader nhr = NetlinkMessageHeader (NETLINK_RTM_NEWROUTE, 0, 
+                                                                   nlmsg.GetHeader ().GetMsgSeq (), m_srcPid);
+                  RouteMessage rtmsg;
+
+                  //fill rtmsg and attributes
+                  rtmsg.SetFamily (AF_INET6);
+                  rtmsg.SetDstLength (32);
+                  rtmsg.SetSrcLength (0);
+                  rtmsg.SetTos (0);//not clear
+                  rtmsg.SetTableId (RouteMessage::RT_TABLE_MAIN);
+                  rtmsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
+                  rtmsg.SetProtocol (RouteMessage::RT_PROT_UNSPEC);
+                  rtmsg.SetFlags (RouteMessage::RT_F_CLONED);
+
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_DST, ADDRESS, route.GetDest ()));
+                  //ns3 use local address as the route src address
+                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_SRC, ADDRESS, ipv6->GetSourceAddress(route.GetDest ())));
+                  // rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_PREFSRC, ADDRESS, ipv6->GetSourceAddress(route.GetDest ())));
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_IIF, U32, route.GetInterface ()));
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_OIF, U32, route.GetInterface ()));
+                  rtmsg.AppendAttribute (NetlinkAttribute (RouteMessage::RT_A_GATEWAY, ADDRESS, route.GetGateway ()));
+
+                  //fill an netlink message body
+                  nlmsg_route.SetHeader (nhr);
+                  nlmsg_route.SetRouteMessage (rtmsg);
+
+                  SendMessageUnicast (nlmsg_route, m_srcPid, 1);
+                  get_flag = 1;
+                }
+            }
+        }
+      
+      if (!get_flag)
+        {
+          NS_LOG_INFO ("no route entry exist by dest address" << dest);
+          m_errno = ERROR_INVAL;
+          return -1;
+        }
+    }
+
+  //then send an broadcast message, let all user know this operation happened
+  MultipartNetlinkMessage nlmsg_multi;
+  NetlinkMessage nlmsg_broadcast = nlmsg;
+  NetlinkMessage nlmsg_done;
+  NetlinkMessageHeader nhr_done = NetlinkMessageHeader (NETLINK_MSG_DONE, NETLINK_MSG_F_MULTI, 0, 0);
+  nlmsg_done.SetHeader (nhr_done);
+  nlmsg_multi.AppendMessage (nlmsg);
+  nlmsg_multi.AppendMessage (nlmsg_done);
+  SendMessageBroadcast (nlmsg_multi, 0, NETLINK_RTM_GRP_IPV4_ROUTE, GetNode ());
+  //   SendMessageBroadcast(nlmsg_broadcast, 0, RTMGRP_IPV6_ROUTE);
+  return 0;
+}
+
+int32_t
+NetlinkSocket::NotifyIfLinkMessage (Address address, uint16_t type, uint8_t family)
+{
+  NS_ASSERT_MSG (false, "Not implemented yet (NotifyIfLinkMessage)");
+  return 0;
+}
+
+int32_t
+NetlinkSocket::NotifyIfAddrMessage (Ipv6Interface* interface, Ipv6Address addr, int cmd)
+{
+  MultipartNetlinkMessage nlmsg_multi;
+  NetlinkMessage nlmsg_ifa;
+  NetlinkMessageHeader nhr = NetlinkMessageHeader (cmd, NETLINK_MSG_F_MULTI, 0, 0);
+  InterfaceAddressMessage ifamsg;
+
+  NS_ASSERT_MSG (false, "Not implemented yet (NotifyIfAddrMessage)");
+
+  // FIXME!
+  Ipv6Prefix prefix = Ipv6Prefix(64);
+
+  //here get the address mask length
+  uint8_t bytes[16];
+  prefix.GetBytes (bytes);
+  uint8_t mask_len = 0;
+  for (int j = 0; j < 16; j++)
+    {
+      while (bytes[j])
+        {
+          bytes[j] = bytes[j] << 1;
+          mask_len ++;
+        }
+    }
+      
+  ifamsg.SetInterfaceIndex (interface->GetDevice ()->GetIfIndex ());
+  ifamsg.SetFamily (AF_INET6);
+  ifamsg.SetLength (mask_len);
+  ifamsg.SetFlags (0);
+  ifamsg.SetScope (RouteMessage::RT_SCOPE_UNIVERSE);
+
+  ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LOCAL,    ADDRESS, addr));
+  ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ADDRESS,  ADDRESS, addr));
+  //  ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_BROADCAST,ADDRESS, bcast));
+  //      ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_LABEL,    STRING,  "ns3-ifaddr"));//not used in ns3
+  //ifamsg.AppendAttribute (NetlinkAttribute (InterfaceAddressMessage::IF_A_ANYCAST,  ADDRESS, Ipv4Address("0.0.0.0")));//not used in ns3
+  //XXXother attributes not used by ns3
+
+  nlmsg_ifa.SetHeader (nhr);
+  nlmsg_ifa.SetInterfaceAddressMessage (ifamsg);
+
+  NetlinkMessage nlmsg_done;
+  NetlinkMessageHeader nhr_done = NetlinkMessageHeader (NETLINK_MSG_DONE, NETLINK_MSG_F_MULTI, 0, 0);
+  nlmsg_done.SetHeader (nhr_done);
+
+  nlmsg_multi.AppendMessage (nlmsg_ifa);
+  nlmsg_multi.AppendMessage (nlmsg_done);
+
+  SendMessageBroadcast (nlmsg_multi, 0, RTMGRP_IPV6_IFADDR, interface->GetDevice ()->GetNode ());  
+  return 0;
+}
+
+#ifdef FIXME
+int32_t
+NetlinkSocket::NotifyRouteMessage(Ojbect route, uint16_t type, uint8_t family)
+{
+  NetlinkMessage nlmsg_broadcast = nlmsg;
+  NetlinkMessageHeader nhr;
+  NS_ASSERT_MSG (false, "Not implemented yet");
+
+  nhr.SetMsgLen (nlmsg.GetHeader ().GetMsgLen ());
+  nhr.SetMsgType (nlmsg.GetHeader ().GetMsgType ());
+  nlmsg_broadcast.SetHeader (nhr);
+  SendMessageBroadcast (nlmsg_broadcast, 0, RTMGRP_IPV6_ROUTE);
+  return 0;
+}
+#endif
+
+}//namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netlink/netlink-socket.h	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,205 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 Liu Jian
+ *
+ * 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: Liu Jian <liujatp@gmail.com>
+ *         Hajime Tazaki <tazaki@sfc.wide.ad.jp>
+ */
+#ifndef NETLINK_SOCKET_H
+#define NETLINK_SOCKET_H
+
+#include <stdint.h>
+#include <queue>
+#include "netlink-message.h"
+#include "ns3/callback.h"
+#include "ns3/ptr.h"
+#include "ns3/traced-callback.h"
+#include "ns3/socket.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv6-address.h"
+#include "ns3/ipv6-interface.h"
+
+namespace ns3 {
+
+class Node;
+class Packet;
+class NetlinkSocketAddress;
+
+/**
+* \brief A NetlinkSocket is  used  to transfer information 
+between kernel and userspace processes .
+*
+* here we focus on NETLINK_ROUTE: Receives routing and link
+* updates and may be used to modify  the  routing  tables 
+* (both IPv4 and IPv6), IP addresses, link parame- ters, neighbor
+* setups, queueing disciplines, traffic classes and packet 
+* classifiers (see rtnetlink (7)). This socket type is very similar
+* to the linux and BSD "packet" sockets.
+*
+* Here is a summary of the semantics of this class:
+* - Bind: Bind uses only the protocol and device fields of the 
+*       NetlinkSocketAddress.
+*
+* - Send: send the input packet to the underlying kernel space
+*       with its own address. The socket must  be bound.
+*
+* - Recv: receive packet from the kernel space.
+*
+* - Accept: not allowed
+* - Connect: not allowed
+*/
+class NetlinkSocket : public Socket
+{
+public:
+  static TypeId GetTypeId (void);
+
+  NetlinkSocket ();
+  virtual ~NetlinkSocket ();
+
+  void SetNode (Ptr<Node> node);
+
+  virtual enum SocketErrno GetErrno (void) const;
+  virtual enum Socket::SocketType GetSocketType (void) const;
+  virtual Ptr<Node> GetNode (void) const;
+  virtual int Bind (void);
+  virtual int Bind (const Address & address);
+  virtual int Close (void);
+  virtual int ShutdownSend (void);
+  virtual int ShutdownRecv (void);
+  virtual int Connect (const Address &address);
+  virtual int Listen (void);
+  virtual uint32_t GetTxAvailable (void) const;
+  virtual int Send (Ptr<Packet> p, uint32_t flags);
+  virtual int SendTo(Ptr<Packet> p, uint32_t flags, const Address &toAddress);
+  virtual uint32_t GetRxAvailable (void) const;
+  virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags);
+  virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags, 
+                                Address &fromAddress);
+  virtual int GetSockName (Address &address) const; 
+  virtual int GetPeerName (Address &address) const;
+  virtual bool SetAllowBroadcast (bool allowBroadcast);
+  virtual bool GetAllowBroadcast () const;
+
+  uint32_t GetSrcPid (void) const;
+  uint32_t GetSrcGroups (void)const;
+  uint32_t GetDstPid (void) const;
+  uint32_t GetDstGroups (void)const;
+  int32_t NotifyIfAddrMessage (Ipv6Interface* interface, Ipv6Address addr, int cmd);
+  int32_t NotifyIfLinkMessage (Address address, uint16_t type, uint8_t family);
+  //  int32_t NotifyRouteMessage(Ojbect route, uint16_t type, uint8_t family);
+
+private:
+  int DoBind (const NetlinkSocketAddress &address);
+  virtual void DoDispose (void);
+  void ForwardUp (Ptr<Packet> p, NetlinkSocketAddress &address);
+
+
+
+  /**
+ * the functions below were for kernel parsing netlink message,set private here
+ * when netlink msg sent to kernel through netlink socket, it was parsed in kernel
+ * space, then, kernel add/del its route/interface/link table or dump all information
+ * to user space
+ */
+
+  int32_t HandleMessage (const NetlinkMessage &nlmsg);
+  /**
+  * when kernel find the message truncated or user need an ACK response,
+  * it send ACK back to user space, with the error code(0 for ACK, > 0 for error).
+  */
+  void SendAckMessage (const NetlinkMessage &nlmsg, int32_t errorcode);
+
+  /**
+  * \brief unicast an message to user
+  * \param nlmsg the netlink message to transmit
+  * \param pid the netlink pid of destination socket
+  * \param nonbloack always true
+  */
+  int32_t SendMessageUnicast (const MultipartNetlinkMessage &nlmsg, 
+                              uint32_t pid, int32_t nonblock);
+  /**
+  * \brief spread message to netlink group user
+  * \param nlmsg the netlink message to transmit
+  * \param pid the netlink pid of the kernel, always 0
+  * \param group multicast group id
+  */
+  static int32_t SendMessageBroadcast (const MultipartNetlinkMessage &nlmsg, 
+                                       uint32_t pid, uint32_t group, Ptr<Node> node);
+
+  /**
+  * these functions below are for NETLINK_ROUTE protocol, it handle the netlink 
+  * message like linux kernel work.  this implementation follows the kernel code 
+  * linux/rtnetlink.c, focus on "interface address, interface info and route entry",
+  * now we will only simply support three types operations of  NETLINK_ROUTE 
+  * protocol
+  */
+  
+  /**
+  * \returns 0 if messge not processed, < 0 for success or an error.
+  * this function would call dumping/doing functions to  
+  */
+  int32_t HandleNetlinkRouteMessage (const NetlinkMessage &nlmsg);
+  
+  /**
+  * \returns 0 if dumping operation is OK, < 0 for an error.
+  */ 
+  int32_t DumpNetlinkRouteMessage (const NetlinkMessage &nlmsg, 
+                                   uint16_t type, uint8_t family);
+  MultipartNetlinkMessage BuildInterfaceAddressDumpMessage (uint32_t pid,
+                                                            uint32_t seq, uint8_t family);
+  MultipartNetlinkMessage BuildInterfaceInfoDumpMessage (uint32_t pid,
+                                                         uint32_t seq, uint8_t family);
+  MultipartNetlinkMessage BuildRouteDumpMessage (uint32_t pid,
+                                                 uint32_t seq, uint8_t family);
+
+  /**
+  * \returns 0 if doing operation(ADD/DEL/GET) is OK, < 0 for an error.
+  */
+  int32_t DoNetlinkRouteMessage (const NetlinkMessage &nlmsg,
+                                 uint16_t type, uint8_t family);
+  int32_t DoInterfaceAddressMessage (const NetlinkMessage &nlmsg, 
+                                     uint16_t type, uint8_t family);
+  int32_t DoInterfaceInfoMessage (const NetlinkMessage &nlmsg, 
+                                  uint16_t type, uint8_t family);
+  int32_t DoRouteMessage (const NetlinkMessage &nlmsg, 
+                          uint16_t type, uint8_t family);
+
+  int ErrnoToSimuErrno (void);
+  Address ConvertFrom (uint8_t family, const Address &address);
+
+  Ptr<Node> m_node;
+  enum SocketErrno m_errno;
+  bool m_shutdownSend;
+  bool m_shutdownRecv;
+
+  std::queue<Ptr<Packet> > m_dataReceiveQueue;
+  uint32_t m_rxAvailable;
+  TracedCallback<Ptr<const Packet> > m_dropTrace;
+  // Socket options (attributes)
+  uint32_t m_rcvBufSize;
+
+  uint32_t m_srcPid;
+  uint32_t m_srcGroups;
+  uint32_t m_dstPid;
+  uint32_t m_dstGroups;
+  Callback<void, Ipv4Address,uint8_t,uint8_t,uint8_t,uint32_t> m_icmpCallback;
+};
+
+}//namespace ns3
+
+#endif /* NETLINK_SOCKET_H */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ns3waf/__init__.py	Thu May 05 09:28:21 2011 +0200
@@ -0,0 +1,465 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+import waflib
+
+def options(opt):
+    opt.tool_options('compiler_cc')
+    opt.tool_options('compiler_cxx')
+    opt.add_option('--enable-static',
+                   help=('Compile module statically: works only on linux, without python'),
+                   dest='enable_static', action='store_true',
+                   default=False)
+    opt.add_option('--disable-log',
+                   help=('Do not compile into the code the log output instructions.'),
+                   dest='enable_log', action='store_false',
+                   default=True)
+    opt.add_option('--disable-assert',
+                   help='Do not compile into the code the assert checks.',
+                   dest='enable_assert', action='store_false',
+                   default=True)
+    opt.add_option('--enable-gcov',
+                   help='Enable code coverage collection.',
+                   dest='enable_gcov', action='store_true',
+                   default=False)
+    opt.add_option('--disable-examples', help='Disable compilation of examples',
+                   dest='enable_examples', action='store_false',
+                   default=True)
+    opt.add_option('--disable-tests', help='Disable compilation of tests',
+                   dest='enable_tests', action='store_false',
+                   default=True)
+    opt.add_option('--disable-debug', help='Disable generation of debug information',
+                   dest='enable_debug', action='store_false',
+                   default=True)
+
+def _report_optional_feature(conf, name, caption, was_enabled, reason_not_enabled):
+    if not 'NS3_OPTIONAL_FEATURES' in conf.env:
+        conf.env['NS3_OPTIONAL_FEATURES'] = []
+    conf.env['NS3_OPTIONAL_FEATURES'].append((name, caption, was_enabled, reason_not_enabled))
+
+
+def _check_compilation_flag(conf, flag, mode='cxx'):
+    """
+    Checks if the C++ compiler accepts a certain compilation flag or flags
+    flag: can be a string or a list of strings
+    """
+    try:
+        if mode == 'cxx':
+            conf.check_cc(fragment='#include <stdio.h>\nint main() { return 0; }\n',
+                          cflags=flag,
+                          execute = False, msg = "Checking for %s" % flag)
+        else:
+            conf.check_cxx(fragment='#include <stdio.h>\nint main() { return 0; }\n',
+                           cxxflags=flag,
+                           execute = False, msg = "Checking for %s" % flag)
+
+    except conf.errors.ConfigurationError:
+        ok = False
+    else:
+        ok = True
+    return ok
+
+
+def _print_optional_features(conf):
+    # Write a summary of optional features status
+    print "---- Summary of optional NS-3 features:"
+    for (name, caption, was_enabled, reason_not_enabled) in conf.env['NS3_OPTIONAL_FEATURES']:
+        if was_enabled:
+            status = 'enabled'
+        else:
+            status = 'not enabled (%s)' % reason_not_enabled
+        print "%-30s: %s" % (caption, status)
+
+def _check_static(conf):
+    import Options
+    import sys
+    import re
+    import os
+    env = conf.env
+    env['NS3_ENABLE_STATIC'] = False
+    if Options.options.enable_static:
+        if sys.platform.startswith('linux') and \
+                env['CXX_NAME'] in ['gcc', 'icc']:
+            if re.match('i[3-6]86', os.uname()[4]):
+                _report_optional_feature(conf, "static", "Static build", True, '')
+                env['NS3_ENABLE_STATIC'] = True
+            elif os.uname()[4] == 'x86_64':
+                if env['NS3_ENABLE_PYTHON_BINDINGS'] and \
+                        not _check_compilation_flag(conf, '-mcmodel=large'):
+                    _report_optional_feature(conf, "static", "Static build", False,
+                                             "Can't enable static builds because " + \
+                                                 "no -mcmodel=large compiler " \
+                                                 "option. Try --disable-python or upgrade your " \
+                                                 "compiler to at least gcc 4.3.x.")
+                else:
+                    _report_optional_feature(conf, "static", "Static build", True, '')
+                    env['NS3_ENABLE_STATIC'] = True                    
+        elif env['CXX_NAME'] == 'gcc' and \
+                (sys.platform.startswith('darwin') or \
+                     sys.platform.startswith('cygwin')):
+                _report_optional_feature(conf, "static", "Static build", True, '')
+                env['NS3_ENABLE_STATIC'] = True
+        else:
+            _report_optional_feature(conf, "static", "Static build", False,
+                                     "Unsupported platform")
+    else:
+        _report_optional_feature(conf, "static", "Static build", False,
+                                 "option --enable-static not selected")
+    # These flags are used for the implicitly dependent modules.
+    if env['NS3_ENABLE_STATIC']:
+        if sys.platform == 'darwin':
+            env['STLIB_MARKER'] = '-Wl,-all_load'
+        else:
+            env['STLIB_MARKER'] = '-Wl,--whole-archive,-Bstatic'
+            env['SHLIB_MARKER'] = '-Wl,-Bdynamic,--no-whole-archive'
+
+def _check_win32(conf):
+    import Options
+    import sys
+    import subprocess
+    import os
+    env = conf.env
+    if conf.env['CXX_NAME'] in ['gcc', 'icc']:
+        if sys.platform == 'win32':
+            env.append_value("LINKFLAGS", "-Wl,--enable-runtime-pseudo-reloc")
+        elif sys.platform == 'cygwin':
+            env.append_value("LINKFLAGS", "-Wl,--enable-auto-import")
+
+        cxx, = env['CXX']
+
+        p = subprocess.Popen([cxx, '-print-file-name=libstdc++.so'], stdout=subprocess.PIPE)
+        libstdcxx_location = os.path.dirname(p.stdout.read().strip())
+        p.wait()
+        if libstdcxx_location:
+            conf.env.append_value('NS3_MODULE_PATH', libstdcxx_location)
+
+        if Options.platform in ['linux']:
+            if _check_compilation_flag(conf, '-Wl,--soname=foo'):
+                env['WL_SONAME_SUPPORTED'] = True
+
+
+def _check_dependencies(conf, required, mandatory):
+    found = []
+    for module in required:
+        retval = conf.check_cfg(package = 'libns3-%s' % module.lower(),
+                                args='--cflags --libs', mandatory=mandatory,
+                                msg="Checking for ns3-%s" % module.lower(),
+                                uselib_store='NS3_%s' % module.upper())
+        if not retval is None:
+            found.append(module)
+    import copy
+    if not 'NS3_MODULES_FOUND' in conf.env:
+        conf.env['NS3_MODULES_FOUND'] = []
+    conf.env['NS3_MODULES_FOUND'] = conf.env['NS3_MODULES_FOUND'] + copy.copy(found)
+
+def modules_uselib(bld, names):
+    return ['NS3_%s' % name.upper() for name in names] + \
+        ['NS3_LIBRARY_%s' % name.upper() for name in names] + \
+        ['NS3_HEADERS_%s' % name.upper() for name in names]
+
+def modules_found(bld, needed):
+    for module in needed:
+        if not module in bld.env['NS3_MODULES_FOUND']:
+            return False
+    return True
+
+def _c_libname(bld, name):
+    libname = 'ns3-' + name
+    if bld.env['NS3_ENABLE_STATIC']:
+        return bld.env['cstlib_PATTERN'] % libname
+    else:
+        return bld.env['cshlib_PATTERN'] % libname
+
+def check_modules(conf, modules, mandatory = True):
+    import Options
+    import os
+
+    if not 'NS3_CHECK_MODULE_ONCE' in conf.env:
+        conf.env['NS3_CHECK_MODULE_ONCE'] = ''
+        conf.check_tool('compiler_cc')
+        conf.check_tool('compiler_cxx')
+        conf.check_cfg(atleast_pkgconfig_version='0.0.0')
+        _check_win32(conf)
+        _check_static(conf)
+        if Options.options.enable_log:
+            _report_optional_feature(conf, "log", "Logging", True, '')
+            conf.env.append_value('DEFINES', 'NS3_LOG_ENABLE')
+        else:
+            _report_optional_feature(conf, "log", "Logging", False, 
+                                     'option --disable-log selected')
+        if Options.options.enable_assert:
+            _report_optional_feature(conf, "assert", "Assert checks", True, '')
+            conf.env.append_value('DEFINES', 'NS3_ASSERT_ENABLE')
+        else:
+            _report_optional_feature(conf, "assert", "Assert checks", False, 
+                                     'option --disable-assert selected')
+        if Options.options.enable_gcov:
+            _report_optional_feature(conf, "coverage", "Code coverage", True, '')
+            conf.env.append_value('CFLAGS', '-fprofile-arcs')
+            conf.env.append_value('CFLAGS', '-ftest-coverage')
+            conf.env.append_value('CXXFLAGS', '-fprofile-arcs')
+            conf.env.append_value('CXXFLAGS', '-ftest-coverage')
+            conf.env.append_value('LINKFLAGS', '-fprofile-arcs')
+        else:
+            _report_optional_feature(conf, "coverage", "Code coverage", False, 
+                                     'option --enable-gcov not selected')
+        if Options.options.enable_examples:
+            _report_optional_feature(conf, "examples", "Example programs", True, '')
+            conf.env['NS3_ENABLE_EXAMPLES'] = True
+        else:
+            _report_optional_feature(conf, "examples", "Example programs", False, 
+                                     'option --disable-examples selected')
+            conf.env['NS3_ENABLE_EXAMPLES'] = False
+
+        if Options.options.enable_tests:
+            _report_optional_feature(conf, "tests", "Test programs", True, '')
+            conf.env['NS3_ENABLE_TESTS'] = True
+        else:
+            _report_optional_feature(conf, "tests", "Test programs", False, 
+                                     'option --disable-tests selected')
+            conf.env['NS3_ENABLE_TESTS'] = False            
+
+        if Options.options.enable_debug:
+            if 'CXXFLAGS' in conf.env:
+                tmp = conf.env['CXXFLAGS']
+            else:
+                tmp = []
+            conf.env['CXXFLAGS'] = tmp + ['-g']
+            if 'CFLAGS' in conf.env:
+                tmp = conf.env['CFLAGS']
+            else:
+                tmp = []
+            conf.env['CFLAGS'] = tmp + ['-g']
+            _report_optional_feature(conf, "debug", "Debug Symbols", True, '')
+        else:
+            _report_optional_feature(conf, "debug", "Debug Symbols", False, 
+                                     'option --disable-debug selected')
+
+    _check_dependencies(conf, modules, mandatory)
+
+def print_feature_summary(conf):
+    _print_optional_features(conf)
+
+def _dirs(source):
+    import os
+    dirs = [os.path.dirname(s) for s in source]
+    def uniq(l):
+        d = dict()
+        for i in l:
+            d[i] = True
+        return d.keys()
+    return uniq(dirs)
+
+def _build_library(bld, name, *k, **kw):
+    import os
+    source = kw.get('source')
+    if source is None:
+        return
+    cxxflags = []
+    cflags = []
+    linkflags = []
+    ccdefines = ['NS3_MODULE_COMPILATION']
+    cxxdefines = ['NS3_MODULE_COMPILATION']
+    includes = _dirs(source)
+    target = os.path.join('lib', 'ns3-%s' % name)
+    if not bld.env['NS3_ENABLE_STATIC']:
+        if bld.env['CXX_NAME'] in ['gcc', 'icc'] and bld.env['WL_SONAME_SUPPORTED']:
+            linkflags.append('-Wl,--soname=%s' % _c_libname(bld, name))
+            pass
+        elif bld.env['CXX_NAME'] in ['gcc', 'icc'] and \
+                os.uname()[4] == 'x86_64' and \
+                bld.env['NS3_ENABLE_PYTHON_BINDINGS']:
+            # enable that flag for static builds only on x86-64 platforms
+            # when gcc is present and only when we want python bindings
+            # (it's more efficient to not use this option if we can avoid it)
+            cxxflags.append('-mcmodel=large')
+            cflags.append('-mcmodel=large')
+    if bld.env['NS3_ENABLE_STATIC']:
+        lib_type = 'stlib'
+    else:
+        lib_type = 'shlib'
+    features = waflib.Tools.c_aliases.sniff_features(source=source, _type=lib_type)
+    kw['features'] = features
+    kw['target'] = target
+    kw['cxxflags'] = kw.get('cxxflags', []) + cxxflags
+    kw['cflags'] = kw.get('cflags', []) + cflags
+    kw['linkflags'] = kw.get('linkflags', []) + linkflags
+    kw['ccdefines'] = kw.get('ccdefines', []) + ccdefines
+    kw['cxxdefines'] = kw.get('cxxdefines', []) + cxxdefines
+    kw['includes'] = kw.get('includes', []) + includes
+    bld(*k, **kw)
+    bld(name='NS3_LIBRARY_%s' % name.upper(), use=[target])
+
+
+def _build_headers(bld, name, headers):
+    if headers is None:
+        return
+    import os
+    import shutil
+    def run(task):
+        out_dir = os.path.dirname(task.outputs[0].abspath())
+        for header in task.inputs:
+            dst = os.path.join(out_dir, os.path.basename(header.abspath()))
+            src = header.abspath()
+            shutil.copyfile(src, dst)
+
+        outfile = file(task.outputs[0].abspath(), "w")
+
+        print >> outfile, """
+#ifdef NS3_MODULE_COMPILATION
+# error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts."
+#endif
+
+#ifndef NS3_MODULE_%s
+    """ % (name.upper().replace('-', '_'),)
+
+        print >> outfile
+        print >> outfile, "// Module headers:"
+        for header in [src.abspath() for src in task.inputs]:
+            print >> outfile, "#include \"%s\"" % (os.path.basename(header),)
+
+        print >> outfile, "#endif"
+
+        outfile.close()
+    target = os.path.join('include', 'ns3', '%s-module.h' % name)
+    bld(rule=run, source=headers, target=target)
+    bld(use=[target], target='NS3_HEADERS_%s' % name.upper(),
+        export_includes=['include'])
+    bld.install_files(os.path.join('${PREFIX}', 'include', 'ns3'), headers + [target])
+
+
+
+def _lib(bld, dep):
+    libpath = bld.env['LIBPATH_%s' % dep.upper()]
+    linkflags = bld.env['LINKFLAGS_%s' % dep.upper()]
+    libs = bld.env['LIB_%s' % dep.upper()]
+    retval = []
+    for path in libpath:
+        retval.append(bld.env['LIBPATH_ST'] % path)
+    retval = retval + linkflags
+    for lib in libs:
+        retval.append(bld.env['LIB_ST'] % lib)
+    return retval
+
+def _cflags(bld, dep):
+    return bld.env['CFLAGS_%s' % dep]
+def _cxxflags(bld, dep):
+    return bld.env['CXXFLAGS_%s' % dep]
+def _defines(bld, dep):
+    return [bld.env['DEFINES_ST'] % define for define in bld.env['DEFINES_%s' % dep]]
+def _includes(bld, dep):
+    return [bld.env['CPPPATH_ST'] % include for include in bld.env['INCLUDES_%s' % dep]]
+
+def _self_lib(bld, name, libdir):
+    if bld.env['NS3_ENABLE_STATIC']:
+        path_st = 'STLIBPATH_ST'
+        lib_st = 'STLIB_ST'
+        lib_marker = 'STLIB_MARKER'
+    else:
+        path_st = 'LIBPATH_ST'
+        lib_st = 'LIB_ST'
+        lib_marker = 'SHLIB_MARKER'
+    libname = 'ns3-' + name
+    return [bld.env[path_st] % libdir,
+            bld.env[lib_marker],
+            bld.env[lib_st] % libname]
+
+def _generate_pcfile(bld, name, use, prefix, outfilename):
+    import os
+    outfile = open(outfilename, 'w')
+    includedir = os.path.join(prefix, 'include')
+    libdir = os.path.join(prefix, 'lib')
+    libs = _self_lib(bld, name, '${libdir}')
+    for dep in use:
+        libs = libs + _lib(bld,dep)
+    cflags = [bld.env['CPPPATH_ST'] % '${includedir}']
+    for dep in use:
+        cflags = cflags + _cflags(bld, dep) + _cxxflags(bld, dep) + \
+            _defines(bld, dep) + _includes(bld, dep)
+    print >> outfile, """
+prefix=%s
+libdir=%s
+includedir=%s
+
+Name: libns3-%s
+Description: ns-3 module %s
+Version: devel
+Libs: %s
+Cflags: %s
+""" % (prefix, libdir, includedir,
+       name, name, ' '.join(libs), ' '.join(cflags))
+    outfile.close()
+
+def _build_pkgconfig(bld, name, use):
+    import os
+    def run(task):
+        _generate_pcfile(bld, name, use, bld.env['PREFIX'], task.outputs[0].abspath())
+        return 0
+    target = os.path.join('lib', 'pkgconfig', 'libns3-%s.pc' % name)
+    bld(rule=run, target=target, always=True)
+    bld.install_files(os.path.join('${PREFIX}', 'lib', 'pkgconfig'), [target])
+
+class Module:
+    def __init__(self, dirs, bld, name):
+        self._source_dirs = dirs
+        self._bld = bld
+        self._name = name
+    def add_tests(self, name = None, **kw):
+        import copy
+        import os
+        import tempfile
+
+        if not name is None:
+            target='ns3test-%s-%s' % (self._name, name)
+        else:
+            target='ns3test-%s' % self._name
+        target = os.path.join('bin', target)
+
+        uselib = kw.get('use', [])
+        if not modules_uselib(self._bld, [self._name]) in uselib:
+            uselib = uselib + modules_uselib(self._bld, [self._name])
+        kw['use'] = uselib
+        kw['includes'] = kw.get('includes', []) + self._source_dirs
+
+        tmp = self._bld.path.relpath_gen(self._bld.srcnode)
+        objects = []
+        for src in kw['source']:
+            src_target = '%s_object' % src
+            objects.append(src_target)
+            kw_copy = copy.copy (kw)
+            path = os.path.dirname(os.path.join(tmp, src))
+            kw_copy['source'] = [src]
+            kw_copy['target'] = src_target
+            kw_copy['defines'] = kw_copy.get('defines', []) + ['NS_TEST_SOURCEDIR=%s' % path]
+            self._bld.objects(**kw_copy)
+        handle, filename = tempfile.mkstemp(suffix='.cc')
+        os.write (handle, """
+#include "ns3/test.h"
+
+int main (int argc, char *argv[])
+{
+  return ns3::TestRunner::Run(argc, argv);
+}
+""")
+        os.close(handle)
+        kw['source'] = [os.path.relpath(filename, self._bld.bldnode.abspath())]
+        kw['use'] = uselib + objects
+        kw['target'] = target
+        kw['install_path'] = None
+        self._bld.program(**kw)
+
+
+def create_module(bld, name, *k, **kw):
+    _build_library(bld, name, *k, **kw)
+    _build_headers(bld, name, kw.get('headers'))
+    _build_pkgconfig(bld, name, kw.get('use'))
+    return Module(_dirs(kw.get('source')), bld, name)
+
+def build_program(bld, target=None, source = None, use = None):
+    bld.program(source=source, target=target, use=use)
+
+def build_example(bld, target=None, source = None, use = None):
+    if bld.env['NS3_ENABLE_EXAMPLES']:
+        bld.program(source=source, target=target, use=use)
+
+
+
Binary file ns3waf/__init__.pyc has changed
--- a/test/netlink-socket-test.cc	Tue Apr 19 23:13:50 2011 +0200
+++ b/test/netlink-socket-test.cc	Thu May 05 09:28:21 2011 +0200
@@ -32,8 +32,8 @@
 #include "ns3/assert.h"
 #include "ns3/log.h"
 #include "ns3/socket.h"
-#include "ns3/netlink-message.h"
-#include "ns3/netlink-socket-address.h"
+#include "netlink-message.h"
+#include "netlink-socket-address.h"
 #include <sys/socket.h>
 #include <string>
 #include <list>
Binary file waf has changed
--- a/wscript	Tue Apr 19 23:13:50 2011 +0200
+++ b/wscript	Thu May 05 09:28:21 2011 +0200
@@ -4,6 +4,8 @@
 import Options
 import os.path
 import ns3waf
+import sys
+
 
 def options(opt):
     opt.tool_options('compiler_cc') 
@@ -21,11 +23,12 @@
 
 def configure(conf):
     ns3waf.check_modules(conf, ['core', 'network', 'internet'], mandatory = True)
+    ns3waf.check_modules(conf, ['point-to-point'], mandatory = False)
 
     conf.check_tool('compiler_cc')
 
     conf.env.append_value('LINKFLAGS', '-pthread')
-    conf.env['HAVE_DL'] = conf.check (lib='dl')
+    conf.check (lib='dl', mandatory = True)
 
     vg_h = conf.check(header_name='valgrind/valgrind.h', mandatory=False)
     vg_memcheck_h = conf.check(header_name='valgrind/memcheck.h', mandatory=False)
@@ -60,7 +63,89 @@
         conf.check()
         conf.env['KERNEL_STACK'] = Options.options.kernel_stack
 
+    ns3waf.print_feature_summary(conf)
+
+def build_netlink(bld):
+    module_source = [
+        'netlink/netlink-socket.cc',
+        'netlink/netlink-socket-address.cc',
+        'netlink/netlink-socket-factory.cc',
+        'netlink/netlink-attribute.cc',
+        'netlink/netlink-message.cc',
+        'netlink/netlink-message-route.cc',
+        ]
+    module_headers = [
+        'netlink/netlink-socket-factory.h'
+        ]
+    if ns3waf.modules_found(bld, ['internet', 'core']):
+        uselib = ns3waf.modules_uselib(bld, ['internet', 'core'])
+        module = ns3waf.create_module(bld, name='netlink',
+                                      source=module_source,
+                                      headers=module_headers,
+                                      use=uselib)
+
+        if ns3waf.modules_found(bld, ['point-to-point']):
+            module_tests = [
+                'test/netlink-socket-test.cc',
+                ]
+            uselib = ns3waf.modules_uselib(bld, ['internet', 
+                                                 'point-to-point', 
+                                                 'core'])
+            module.add_tests(source=module_tests, use = uselib)
+
+def create_dce_program(bld, **kw):
+    if os.uname()[4] == 'x86_64':
+        mcmodel = ['-mcmodel=large']
+    else:
+        mcmodel = []
+    nofortify = ['-U_FORTIFY_SOURCE']
+    #debug_dl = ['-Wl,--dynamic-linker=/usr/lib/debug/ld-linux-x86-64.so.2']
+    debug_dl = []
+    kw['cxxflags'] = kw.get('cxxflags', []) + ['-fpie'] + mcmodel + nofortify
+    kw['cflags'] = kw.get('cflags', []) + ['-fpie'] + mcmodel + nofortify
+    kw['linkflags'] = kw.get('linkflags', []) + ['-pie'] + debug_dl
+    bld.program(**kw)
+
+def new_test(bld,name,uselib):
+    obj = create_dce_program(bld, target='bin/' + name, source = ['test/' + name + '.cc'],
+                             use = uselib + ['lib/test'])
+
+
+def build_dce_tests(bld):
+    test = bld.shlib(source=['test/test-macros.cc'], target='lib/test',
+                     linkflags=['-Wl,-soname=libtest.so'])
+
+    tests = [['test-empty', []],
+             ['test-sleep', []],
+             ['test-nanosleep', []],
+             ['test-pthread', ['PTHREAD']],
+             ['test-mutex', ['PTHREAD']],
+             ['test-once', ['PTHREAD']],
+             ['test-pthread-key', ['PTHREAD']],
+             ['test-sem', ['PTHREAD']],
+             ['test-malloc', []],
+             ['test-malloc-2', []],
+             ['test-fd-simple', []],
+             ['test-strerror', []],
+             ['test-stdio', []],
+             ['test-string', []],
+             ['test-netdb', []],
+             ['test-env', []],
+             ['test-cond', ['PTHREAD']],
+             ['test-timer-fd', []],
+             ['test-stdlib', []],
+             ['test-select', []],
+             ['test-random', []],
+             ['test-ioctl', []],
+             ['test-fork', []],
+             ]
+    for name,uselib in tests:
+        new_test(bld, name, uselib)
+
+
 def build(bld):
+    build_netlink(bld)
+
     if bld.env['KERNEL_STACK']:
         kernel_source = [
             'linux-socket-fd-factory.cc',
@@ -119,13 +204,6 @@
         'model/dlm-loader-factory.cc',
         'model/socket-fd-factory.cc',
         'model/ns3-socket-fd-factory.cc',
-        # netlink code
-        'model/netlink-socket.cc',
-        'model/netlink-socket-address.cc',
-        'model/netlink-socket-factory.cc',
-        'model/netlink-attribute.cc',
-        'model/netlink-message.cc',
-        'model/netlink-message-route.cc',
         # helper.
         'helper/dce-manager-helper.cc',
         'helper/dce-application-helper.cc',
@@ -139,24 +217,21 @@
 	'model/dce-application.h',
         'helper/dce-manager-helper.h',
         'helper/dce-application-helper.h',
-# needed only for test module.
-        'model/netlink-message.h',
-        'model/netlink-message-route.h',
-        'model/netlink-attribute.h',
-        'model/netlink-socket-address.h',
         ]
     module_source = module_source + kernel_source
     module_headers = module_headers + kernel_headers
-    module_test = [
+    uselib = ns3waf.modules_uselib(bld, ['core', 'network', 'internet', 'netlink'])
+    module = ns3waf.create_module(bld, name='dce',
+                                  source=module_source,
+                                  headers=module_headers,
+                                  use=uselib,
+                                  includes=kernel_includes,
+                                  lib=['dl'])
+    module_tests = [
         'test/dce-manager-test.cc',
-        'test/netlink-socket-test.cc',
         ]
-    uselib = ns3waf.modules_uselib(bld, ['core', 'network', 'internet'])
-    ns3waf.build_module(bld, name='dce',
-                        source=module_source,
-                        headers=module_headers,
-                        use=uselib,
-                        includes=kernel_includes)
+    module.add_tests(source=module_tests, use = uselib)
+    build_dce_tests (bld)
 
     bld.add_group('dce_version_files')
 
@@ -175,7 +250,7 @@
     # The very small libc used to replace the glibc
     # and forward to the dce_* code
     bld.shlib(source = ['model/libc.c', 'model/libc-global-variables.c'],
-              target='c-ns3', cflags=['-g'],
+              target='lib/c-ns3', cflags=['-g'],
               defines=['LIBSETUP=libc_setup'],
               linkflags=['-nostdlib', 
                          '-Wl,--version-script=' + os.path.join('model', 'libc.version'),
@@ -184,7 +259,7 @@
     # The very small libpthread used to replace the glibc
     # and forward to the dce_* code
     bld.shlib(source = ['model/libc.c'],
-              target='pthread-ns3', cflags=['-g'],
+              target='lib/pthread-ns3', cflags=['-g'],
               defines=['LIBSETUP=libpthread_setup'],
               linkflags=['-nostdlib', '-lc',
                          '-Wl,--version-script=' + os.path.join('model', 'libpthread.version'),