--- /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'),