src/node/nsc-sysctl.cc
author Florian Westphal <fw@strlen.de>
Wed Jul 15 18:46:14 2009 +0200 (2009-07-15)
changeset 4685 ae536d9e0d6d
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  * This program is free software; you can redistribute it and/or modify
     4  * it under the terms of the GNU General Public License version 2 as
     5  * published by the Free Software Foundation;
     6  *
     7  * This program is distributed in the hope that it will be useful,
     8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    10  * GNU General Public License for more details.
    11  *
    12  * You should have received a copy of the GNU General Public License
    13  * along with this program; if not, write to the Free Software
    14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    15  *
    16  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
    17  */
    18 
    19 #include "ns3/string.h"
    20 #include "nsc-sysctl.h"
    21 
    22 #include "sim_interface.h"
    23 
    24 namespace ns3 {
    25 
    26 class NscStackStringAccessor : public AttributeAccessor
    27 {
    28   public:
    29   NscStackStringAccessor (std::string name) : m_name (name) {}
    30 
    31   virtual bool Set (ObjectBase * object, const AttributeValue &val) const;
    32   virtual bool Get (const ObjectBase * object, AttributeValue &val) const;
    33   virtual bool HasGetter (void) const;
    34   virtual bool HasSetter (void) const;
    35   private:
    36   std::string m_name;
    37 };
    38 
    39 bool NscStackStringAccessor::HasGetter(void) const
    40 {
    41   return true;
    42 }
    43 
    44 bool NscStackStringAccessor::HasSetter(void) const
    45 {
    46   return true;
    47 }
    48 
    49 
    50 bool NscStackStringAccessor::Set (ObjectBase * object, const AttributeValue & val) const
    51 {
    52   const StringValue *value = dynamic_cast<const StringValue *> (&val);
    53   if (value == 0)
    54     {
    55       return false;
    56     }
    57   Ns3NscStack *obj = dynamic_cast<Ns3NscStack *> (object);
    58   if (obj == 0)
    59     {
    60       return false;
    61     }
    62   obj->Set (m_name, value->Get ());
    63   return true;
    64 }
    65 
    66 bool NscStackStringAccessor::Get (const ObjectBase * object, AttributeValue &val) const
    67 {
    68   StringValue *value = dynamic_cast<StringValue *> (&val);
    69   if (value == 0)
    70     {
    71       return false;
    72     }
    73   const Ns3NscStack *obj = dynamic_cast<const Ns3NscStack *> (object);
    74   if (obj == 0)
    75     {
    76       return false;
    77     }
    78   value->Set (obj->Get (m_name));
    79   return true;
    80 }
    81 
    82 
    83 TypeId
    84 Ns3NscStack::GetInstanceTypeId (void) const
    85 {
    86   if (m_stack == 0)
    87     {
    88       // if we have no stack, we are a normal NscStack without any attributes.
    89       return GetTypeId ();
    90     }
    91   std::string name = "ns3::Ns3NscStack<";
    92   name += m_stack->get_name ();
    93   name += ">";
    94   TypeId tid;
    95   if (TypeId::LookupByNameFailSafe (name, &tid))
    96     {
    97       // if the relevant TypeId has already been registered, no need to do it again.
    98       return tid;
    99     }
   100   else
   101     {
   102       // Now, we register a new TypeId for this stack which will look
   103       // like a subclass of the Ns3NscStack. The class Ns3NscStack is effectively
   104       // mutating into a subclass of itself from the point of view of the TypeId
   105       // system _here_
   106       tid = TypeId (name.c_str ());
   107       tid.SetParent<Ns3NscStack> ();
   108       char buf[256];
   109       for (int i=0; m_stack->sysctl_getnum(i, buf, sizeof(buf)) > 0 ;i++)
   110         {
   111           char value[256];
   112           if (m_stack->sysctl_get (buf, value, sizeof(value)) > 0)
   113             {
   114               tid.AddAttribute (buf, "Help text",
   115                                 StringValue (value),
   116                                 Create<NscStackStringAccessor> (buf),
   117                                 MakeStringChecker ());
   118             }
   119         }
   120       return tid;
   121     }
   122 }
   123 
   124 std::string
   125 Ns3NscStack::Get (std::string name) const
   126 {
   127   char buf[512];
   128   if (m_stack->sysctl_get (name.c_str (), buf, sizeof(buf)) <= 0)
   129     { // name.c_str () is not a valid sysctl name, or internal NSC error (eg. error converting value)
   130       return NULL;
   131     }
   132   return std::string(buf);
   133 }
   134 
   135 void
   136 Ns3NscStack::Set (std::string name, std::string value)
   137 {
   138   int ret = m_stack->sysctl_set (name.c_str (), value.c_str ());
   139   if (ret < 0)
   140     {
   141       NS_FATAL_ERROR ("setting " << name << " to " << value << "failed (retval " << ret << ")");
   142     }
   143 }
   144 
   145 TypeId
   146 Ns3NscStack::Ns3NscStack::GetTypeId (void)
   147 {
   148   static TypeId tid = TypeId ("ns3::Ns3NscStack")
   149   .SetParent<Object> ()
   150   ;
   151   return tid;
   152 }
   153 
   154 } // namespace ns3