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