src/node/node.cc
author Florian Westphal <fw@strlen.de>
Wed Jul 15 18:46:14 2009 +0200 (2009-07-15)
changeset 4685 ae536d9e0d6d
parent 4578 88434ff8f0a5
permissions -rw-r--r--
nsc: move nsc glue code from nsc-tcp-l4-protocol to node/nsc-glue.cc.

known problems:
- sim_interface.h is duplicated
- nsc-glue.cc adds hooks in node.cc, "hijacks" incoming packets
- nsc-glue exports NSCs INetStack (instead of wrapping it completely)
- nsc-tcp-l4-protocol and nsc-tcp-socket-impl make calls into nsc-glue
- nsc-tcp-socket-impl should really be "nsc-socket-core" (or something
like that)

needs fixing on nsc side:
- no support for multiple interfaces yet (also not yet supported
on nsc side)
- nsc initialisation still tied to IP (Adding an Interface and assigning the
IP address is a single step; it should be separate)

maybe there is more.

There is a NSC_NEXT define in nsc-glue.h, its main purpose is to flag
the places where the NSC API needs to be adapted to support multiple
interfaces in nsc.
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     3  * Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program; if not, write to the Free Software
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    18  * Authors: George F. Riley<riley@ece.gatech.edu>
    19  *          Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    20  */
    21 #include "node.h"
    22 #include "node-list.h"
    23 #include "net-device.h"
    24 #include "application.h"
    25 #include "ns3/packet.h"
    26 #include "ns3/simulator.h"
    27 #include "ns3/object-vector.h"
    28 #include "ns3/uinteger.h"
    29 #include "ns3/log.h"
    30 #include "ns3/assert.h"
    31 #include "ns3/global-value.h"
    32 #include "ns3/boolean.h"
    33 
    34 #include "nsc-glue.h"
    35 
    36 NS_LOG_COMPONENT_DEFINE ("Node");
    37 
    38 namespace ns3{
    39 
    40 NS_OBJECT_ENSURE_REGISTERED (Node);
    41 
    42 GlobalValue g_checksumEnabled  = GlobalValue ("ChecksumEnabled",
    43                                               "A global switch to enable all checksums for all protocols",
    44                                               BooleanValue (false),
    45                                               MakeBooleanChecker ());
    46 
    47 TypeId 
    48 Node::GetTypeId (void)
    49 {
    50   static TypeId tid = TypeId ("ns3::Node")
    51     .SetParent<Object> ()
    52     .AddConstructor<Node> ()
    53     .AddAttribute ("DeviceList", "The list of devices associated to this Node.",
    54                    ObjectVectorValue (),
    55                    MakeObjectVectorAccessor (&Node::m_devices),
    56                    MakeObjectVectorChecker<NetDevice> ())
    57     .AddAttribute ("ApplicationList", "The list of applications associated to this Node.",
    58                    ObjectVectorValue (),
    59                    MakeObjectVectorAccessor (&Node::m_applications),
    60                    MakeObjectVectorChecker<Application> ())
    61     .AddAttribute ("Id", "The id (unique integer) of this Node.",
    62                    TypeId::ATTR_GET, // allow only getting it.
    63                    UintegerValue (0),
    64                    MakeUintegerAccessor (&Node::m_id),
    65                    MakeUintegerChecker<uint32_t> ())
    66     ;
    67   return tid;
    68 }
    69 
    70 Node::Node()
    71   : m_id(0), 
    72     m_sid(0),
    73     m_useNsc(false)
    74 {
    75   Construct ();
    76 }
    77 
    78 Node::Node(uint32_t sid)
    79   : m_id(0), 
    80     m_sid(sid)
    81 { 
    82   Construct ();
    83 }
    84 
    85 void
    86 Node::Construct (void)
    87 {
    88   m_id = NodeList::Add (this);
    89 }
    90   
    91 Node::~Node ()
    92 {}
    93 
    94 uint32_t 
    95 Node::GetId (void) const
    96 {
    97   return m_id;
    98 }
    99 
   100 uint32_t 
   101 Node::GetSystemId (void) const
   102 {
   103   return m_sid;
   104 }
   105 
   106 uint32_t 
   107 Node::AddDevice (Ptr<NetDevice> device)
   108 {
   109   uint32_t index = m_devices.size ();
   110   m_devices.push_back (device);
   111   device->SetNode (this);
   112   device->SetIfIndex(index);
   113   device->SetReceiveCallback (MakeCallback (&Node::NonPromiscReceiveFromDevice, this));
   114   NotifyDeviceAdded (device);
   115   return index;
   116 }
   117 Ptr<NetDevice>
   118 Node::GetDevice (uint32_t index) const
   119 {
   120   NS_ASSERT_MSG (index < m_devices.size (), "Device index " << index <<
   121                  " is out of range (only have " << m_devices.size () << " devices).");
   122   return m_devices[index];
   123 }
   124 uint32_t 
   125 Node::GetNDevices (void) const
   126 {
   127   return m_devices.size ();
   128 }
   129 
   130 uint32_t 
   131 Node::AddApplication (Ptr<Application> application)
   132 {
   133   uint32_t index = m_applications.size ();
   134   m_applications.push_back (application);
   135   application->SetNode (this);
   136   return index;
   137 }
   138 Ptr<Application> 
   139 Node::GetApplication (uint32_t index) const
   140 {
   141   NS_ASSERT_MSG (index < m_applications.size (), "Application index " << index <<
   142                  " is out of range (only have " << m_applications.size () << " applications).");
   143   return m_applications[index];
   144 }
   145 uint32_t 
   146 Node::GetNApplications (void) const
   147 {
   148   return m_applications.size ();
   149 }
   150 
   151 void 
   152 Node::DoDispose()
   153 {
   154   for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
   155        i != m_devices.end (); i++)
   156     {
   157       Ptr<NetDevice> device = *i;
   158       device->Dispose ();
   159       *i = 0;
   160     }
   161   m_devices.clear ();
   162   for (std::vector<Ptr<Application> >::iterator i = m_applications.begin ();
   163        i != m_applications.end (); i++)
   164     {
   165       Ptr<Application> application = *i;
   166       application->Dispose ();
   167       *i = 0;
   168     }
   169   m_applications.clear ();
   170   Object::DoDispose ();
   171 }
   172 
   173 void 
   174 Node::NotifyDeviceAdded (Ptr<NetDevice> device)
   175 {}
   176 
   177 void
   178 Node::RegisterProtocolHandler (ProtocolHandler handler, 
   179                                uint16_t protocolType,
   180                                Ptr<NetDevice> device,
   181                                bool promiscuous)
   182 {
   183   struct Node::ProtocolHandlerEntry entry;
   184   entry.handler = handler;
   185   entry.protocol = protocolType;
   186   entry.device = device;
   187   entry.promiscuous = promiscuous;
   188 
   189   // On demand enable promiscuous mode in netdevices
   190   if (promiscuous)
   191     {
   192       if (device == 0)
   193         {
   194           for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
   195                i != m_devices.end (); i++)
   196             {
   197               Ptr<NetDevice> dev = *i;
   198               dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
   199             }
   200         }
   201       else
   202         {
   203           device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
   204         }
   205     }
   206 
   207   m_handlers.push_back (entry);
   208 }
   209 
   210 void
   211 Node::UnregisterProtocolHandler (ProtocolHandler handler)
   212 {
   213   for (ProtocolHandlerList::iterator i = m_handlers.begin ();
   214        i != m_handlers.end (); i++)
   215     {
   216       if (i->handler.IsEqual (handler))
   217         {
   218           m_handlers.erase (i);
   219           break;
   220         }
   221     }
   222 }
   223 
   224 bool
   225 Node::ChecksumEnabled (void)
   226 {
   227   BooleanValue val;
   228   g_checksumEnabled.GetValue (val);
   229   return val.Get ();
   230 }
   231 
   232 bool
   233 Node::PromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
   234                                 const Address &from, const Address &to, NetDevice::PacketType packetType)
   235 {
   236   NS_LOG_FUNCTION(this);
   237   return ReceiveFromDevice (device, packet, protocol, from, to, packetType, true);
   238 }
   239 
   240 bool
   241 Node::NonPromiscReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
   242                                    const Address &from)
   243 {
   244   NS_LOG_FUNCTION(this);
   245   return ReceiveFromDevice (device, packet, protocol, from, from, NetDevice::PacketType (0), false);
   246 }
   247 
   248 bool
   249 Node::ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
   250                          const Address &from, const Address &to, NetDevice::PacketType packetType, bool promiscuous)
   251 {
   252   NS_LOG_DEBUG("Node " << GetId () << " ReceiveFromDevice:  dev "
   253                << device->GetIfIndex () << " (type=" << device->GetInstanceTypeId ().GetName ()
   254                << ") Packet UID " << packet->GetUid ());
   255   bool found = false;
   256 
   257   if (m_useNsc && m_nscGlue->IsNscProtocol (protocol)) {
   258       m_nscGlue->PassPacketToNsc (packet, 0); // 0: NSC interface ID. XXX: Map &device <-> nscindex
   259       return true;
   260   }
   261 
   262   for (ProtocolHandlerList::iterator i = m_handlers.begin ();
   263        i != m_handlers.end (); i++)
   264     {
   265       if (i->device == 0 ||
   266           (i->device != 0 && i->device == device))
   267         {
   268           if (i->protocol == 0 || 
   269               i->protocol == protocol)
   270             {
   271               if (promiscuous == i->promiscuous)
   272                 {
   273                   i->handler (device, packet, protocol, from, to, packetType);
   274                   found = true;
   275                 }
   276             }
   277         }
   278     }
   279   return found;
   280 }
   281 
   282 #ifdef NETWORK_SIMULATION_CRADLE
   283 void
   284 Node::SetNscLibrary(const std::string &soname)
   285 {
   286   m_nscGlue = CreateObject <NscGlue> ();
   287   m_nscGlue->SetNode (this);
   288   m_nscGlue->SetNscLibrary (soname);
   289 
   290   m_useNsc = true;
   291 }
   292 
   293 std::string
   294 Node::GetNscLibrary(void) const
   295 {
   296   return m_nscGlue->GetNscLibrary ();
   297 }
   298 
   299 
   300 
   301 INetStack *
   302 Node::GetNscInetStack(void)
   303 {
   304   NS_ASSERT_MSG(m_useNsc, "GetNscInetStack called, but nsc disabled on this node");
   305   return m_nscGlue->m_nscStack;
   306 }
   307 
   308 void Node::RegisterNscWakeupCallback(Callback<void> cb)
   309 {
   310   NS_ASSERT (m_nscGlue);
   311   m_nscGlue->RegisterWakeupCallback (cb);
   312 }
   313 #endif
   314 }//namespace ns3