25 #include "ns3/simulator.h" 
   27 #include "ns3/random-variable-stream.h" 
   28 #include "ns3/mac48-address.h" 
   29 #include "ns3/ipv4-interface.h" 
   30 #include "ns3/ipv4-l3-click-protocol.h" 
   44 #define INTERFACE_ID_KERNELTAP 0 
   45 #define INTERFACE_ID_FIRST 1 
   46 #define INTERFACE_ID_FIRST_DROP 33 
   50 std::map < simclick_node_t *, Ptr<Ipv4ClickRouting> > Ipv4ClickRouting::m_clickInstanceFromSimNode;
 
   55   static TypeId tid = TypeId (
"ns3::Ipv4ClickRouting")
 
   57     .AddConstructor<Ipv4ClickRouting> ()
 
   63 Ipv4ClickRouting::Ipv4ClickRouting ()
 
   64   : m_nonDefaultName (false),
 
   67   m_random = CreateObject<UniformRandomVariable> ();
 
   68   m_simNode = 
new simclick_node_t;
 
   69   timerclear (&m_simNode->curtime);
 
   71   AddSimNodeToClickMapping ();
 
   74 Ipv4ClickRouting::~Ipv4ClickRouting ()
 
   79 Ipv4ClickRouting::DoInitialize ()
 
   81   uint32_t 
id = m_ipv4->GetObject<Node> ()->GetId ();
 
   83   if (!m_nonDefaultName)
 
   85       std::stringstream name;
 
   87       m_nodeName = name.str ();
 
   94   if (simclick_click_create (m_simNode, m_clickFile.c_str ()) >= 0)
 
   96       NS_LOG_DEBUG (m_nodeName << 
" has initialised a Click Router");
 
   97       m_clickInitialised = 
true;
 
  101       NS_LOG_DEBUG (
"Click Router Initialisation failed for " << m_nodeName);
 
  102       m_clickInitialised = 
false;
 
  106   simclick_click_run (m_simNode);
 
  115 Ptr<UniformRandomVariable>
 
  116 Ipv4ClickRouting::GetRandomVariable (
void)
 
  122 Ipv4ClickRouting::DoDispose ()
 
  124   if (m_clickInitialised)
 
  126       simclick_click_kill (m_simNode);
 
  130   Ipv4RoutingProtocol::DoDispose ();
 
  134 Ipv4ClickRouting::SetClickFile (std::string clickfile)
 
  136   m_clickFile = clickfile;
 
  140 Ipv4ClickRouting::SetDefines (std::map<std::string, std::string> defines)
 
  145 std::map<std::string, std::string>
 
  146 Ipv4ClickRouting::GetDefines (
void)
 
  152 Ipv4ClickRouting::SetClickRoutingTableElement (std::string name)
 
  154   m_clickRoutingTableElement = name;
 
  158 Ipv4ClickRouting::SetNodeName (std::string name)
 
  161   m_nonDefaultName = 
true;
 
  165 Ipv4ClickRouting::GetNodeName ()
 
  171 Ipv4ClickRouting::GetInterfaceId (
const char *ifname)
 
  187   if (strstr (ifname, 
"tap") || strstr (ifname, 
"tun"))
 
  191   else if (
const char *devname = strstr (ifname, 
"eth"))
 
  193       while (*devname && !isdigit ((
unsigned char) *devname))
 
  200           retval = atoi (devname) + INTERFACE_ID_FIRST;
 
  203   else if (
const char *devname = strstr (ifname, 
"drop"))
 
  205       while (*devname && !isdigit ((
unsigned char) *devname))
 
  211           retval = atoi (devname) + INTERFACE_ID_FIRST_DROP;
 
  219   if (retval >= (
int) m_ipv4->GetNInterfaces ())
 
  228 Ipv4ClickRouting::IsInterfaceReady (
int ifid)
 
  230   if (ifid >= 0 && ifid < (
int) m_ipv4->GetNInterfaces ())
 
  241 Ipv4ClickRouting::GetIpAddressFromInterfaceId (
int ifid)
 
  243   std::stringstream addr;
 
  244   m_ipv4->GetAddress (ifid, 0).GetLocal ().Print (addr);
 
  250 Ipv4ClickRouting::GetIpPrefixFromInterfaceId (
int ifid)
 
  252   std::stringstream addr;
 
  253   m_ipv4->GetAddress (ifid, 0).GetMask ().Print (addr);
 
  259 Ipv4ClickRouting::GetMacAddressFromInterfaceId (
int ifid)
 
  261   std::stringstream addr;
 
  263   Ptr<NetDevice> device = m_ipv4->GetNetDevice (ifid);
 
  264   Address devAddr = device->GetAddress ();
 
  265   addr << Mac48Address::ConvertFrom (devAddr);
 
  271 Ipv4ClickRouting::AddSimNodeToClickMapping ()
 
  273   m_clickInstanceFromSimNode.insert (std::make_pair (m_simNode, 
this));
 
  276 Ptr<Ipv4ClickRouting>
 
  277 Ipv4ClickRouting::GetClickInstanceFromSimNode (simclick_node_t *simnode)
 
  279   return m_clickInstanceFromSimNode[simnode];
 
  283 Ipv4ClickRouting::GetTimevalFromNow () const
 
  285   struct timeval curtime;
 
  286   uint64_t remainder = 0;
 
  309       if (curtime.tv_usec == 1000000)
 
  320 Ipv4ClickRouting::RunClickEvent ()
 
  322   m_simNode->curtime = GetTimevalFromNow ();
 
  324   NS_LOG_DEBUG (
"RunClickEvent at " << m_simNode->curtime.tv_sec << 
" " << 
 
  326   simclick_click_run (m_simNode);
 
  330 Ipv4ClickRouting::HandleScheduleFromClick (
const struct timeval *when)
 
  334   Time simtime  = Time::FromInteger(when->tv_sec, Time::S) + Time::FromInteger(when->tv_usec, Time::US);
 
  337   Simulator::Schedule (simdelay, &Ipv4ClickRouting::RunClickEvent, 
this);
 
  341 Ipv4ClickRouting::HandlePacketFromClick (
int ifid, 
int ptype, 
const unsigned char* 
data, 
int len)
 
  350       NS_LOG_DEBUG (
"Incoming packet from tap0. Sending Packet up the stack.");
 
  351       Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
 
  353       Ptr<Packet> p = Create<Packet> (
data, len);
 
  356       p->RemoveHeader (ipHeader);
 
  358       ipv4l3->LocalDeliver (p, ipHeader, (uint32_t) ifid);
 
  362       NS_LOG_DEBUG (
"Incoming packet from eth" << ifid - 1 << 
" of type " << ptype << 
". Sending packet down the stack.");
 
  364       Ptr<Packet> p = Create<Packet> (
data, len);
 
  366       DynamicCast<Ipv4L3ClickProtocol> (m_ipv4)->SendDown (p, ifid);
 
  371 Ipv4ClickRouting::SendPacketToClick (
int ifid, 
int ptype, 
const unsigned char* data, 
int len)
 
  374   m_simNode->curtime = GetTimevalFromNow ();
 
  378   simclick_simpacketinfo pinfo;
 
  382   simclick_click_send (m_simNode,ifid,ptype,data,len,&pinfo);
 
  386 Ipv4ClickRouting::Send (Ptr<Packet> p, Ipv4Address src, Ipv4Address dst)
 
  391   for (ifid = 0; ifid < m_ipv4->GetNInterfaces (); ifid++)
 
  393       Ipv4Address addr = m_ipv4->GetAddress (ifid, 0).GetLocal ();
 
  401   int len = p->GetSize ();
 
  402   uint8_t *buf = 
new uint8_t [len];
 
  403   p->CopyData (buf, len);
 
  406   SendPacketToClick (0, SIMCLICK_PTYPE_IP, buf, len);
 
  412 Ipv4ClickRouting::Receive (Ptr<Packet> p, Mac48Address receiverAddr, Mac48Address dest)
 
  419   for (ifid = 0; ifid < m_ipv4->GetNInterfaces (); ifid++)
 
  421       Ptr<NetDevice> device = m_ipv4->GetNetDevice (ifid);
 
  423       if (Mac48Address::ConvertFrom (device->GetAddress ()) == receiverAddr)
 
  429   int len = p->GetSize ();
 
  430   uint8_t *buf = 
new uint8_t [len];
 
  431   p->CopyData (buf, len);
 
  434   SendPacketToClick (ifid, SIMCLICK_PTYPE_ETHER, buf, len);
 
  440 Ipv4ClickRouting::ReadHandler (std::string elementName, std::string handlerName)
 
  442   char *handle = simclick_click_read_handler (m_simNode, elementName.c_str (), handlerName.c_str (), 0, 0);
 
  443   std::string ret (handle);
 
  454 Ipv4ClickRouting::WriteHandler (std::string elementName, std::string handlerName, std::string writeString)
 
  456   int r = simclick_click_write_handler (m_simNode, elementName.c_str (), handlerName.c_str (), writeString.c_str ());
 
  468 Ipv4ClickRouting::SetPromisc (
int ifid)
 
  470   Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
 
  472   ipv4l3->SetPromisc (ifid);
 
  476 Ipv4ClickRouting::RouteOutput (Ptr<Packet> p, 
const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
 
  478   Ptr<Ipv4Route> rtentry;
 
  480   std::stringstream addr;
 
  482   header.GetDestination ().Print (addr);
 
  485   std::string 
s = ReadHandler (m_clickRoutingTableElement, addr.str ());
 
  487   int pos = s.find (
" ");
 
  489   int interfaceId = atoi (s.substr (0, pos).c_str ());
 
  490   Ipv4Address destination (s.substr (pos + 1).c_str ());
 
  492   if (interfaceId != -1)
 
  494       rtentry = Create<Ipv4Route> ();
 
  495       rtentry->SetDestination (header.GetDestination ());
 
  500       uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceId);
 
  502       Ipv4InterfaceAddress ifAddr;
 
  503       if (numOifAddresses == 1)
 
  505           ifAddr = m_ipv4->GetAddress (interfaceId, 0);
 
  510           NS_FATAL_ERROR (
"XXX Not implemented yet:  IP aliasing and Click");
 
  512       rtentry->SetSource (ifAddr.GetLocal ());
 
  513       rtentry->SetGateway (destination);
 
  514       rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceId));
 
  515       sockerr = Socket::ERROR_NOTERROR;
 
  516       NS_LOG_DEBUG (
"Found route to " << rtentry->GetDestination ()
 
  517                                       << 
" via nh " << rtentry->GetGateway ()
 
  518                                       << 
" with source addr " << rtentry->GetSource ()
 
  519                                       << 
" and output dev " << rtentry->GetOutputDevice ());
 
  524                                   << 
": RouteOutput for dest=" << header.GetDestination ()
 
  525                                   << 
" No route to host");
 
  526       sockerr = Socket::ERROR_NOROUTETOHOST;
 
  535 Ipv4ClickRouting::RouteInput  (Ptr<const Packet> p, 
const Ipv4Header &header,
 
  536                                Ptr<const NetDevice> idev, UnicastForwardCallback ucb,
 
  537                                MulticastForwardCallback mcb, LocalDeliverCallback lcb,
 
  540   NS_FATAL_ERROR (
"Click router does not have a RouteInput() interface!");
 
  545 Ipv4ClickRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream)
 const 
  550 Ipv4ClickRouting::NotifyInterfaceUp (uint32_t i)
 
  555 Ipv4ClickRouting::NotifyInterfaceDown (uint32_t i)
 
  560 Ipv4ClickRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress 
address)
 
  565 Ipv4ClickRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress 
address)
 
  572 static int simstrlcpy (
char *buf, 
int len, 
const std::string &s)
 
  578       if ((
unsigned) len > s.length ())
 
  591 int simclick_sim_send (simclick_node_t *simnode,
 
  592                        int ifid, 
int type, 
const unsigned char* data, 
int len,
 
  593                        simclick_simpacketinfo *pinfo)
 
  604   clickInstance->HandlePacketFromClick (ifid, type, data, len);
 
  610 int simclick_sim_command (simclick_node_t *simnode, 
int cmd, ...)
 
  620     case SIMCLICK_VERSION:
 
  626     case SIMCLICK_SUPPORTS:
 
  628         int othercmd = va_arg (val, 
int);
 
  629         retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
 
  633     case SIMCLICK_IFID_FROM_NAME:
 
  635         const char *ifname = va_arg (val, 
const char *);
 
  637         retval = clickInstance->GetInterfaceId (ifname);
 
  639         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" SIMCLICK_IFID_FROM_NAME: " << ifname << 
" " << retval);
 
  643     case SIMCLICK_IPADDR_FROM_NAME:
 
  645         const char *ifname = va_arg (val, 
const char *);
 
  646         char *buf = va_arg (val, 
char *);
 
  647         int len = va_arg (val, 
int);
 
  649         int ifid = clickInstance->GetInterfaceId (ifname);
 
  653             retval = simstrlcpy (buf, len, clickInstance->GetIpAddressFromInterfaceId (ifid));
 
  660         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" SIMCLICK_IPADDR_FROM_NAME: " << ifname << 
" " << buf << 
" " << len);
 
  664     case SIMCLICK_IPPREFIX_FROM_NAME:
 
  666         const char *ifname = va_arg (val, 
const char *);
 
  667         char *buf = va_arg (val, 
char *);
 
  668         int len = va_arg (val, 
int);
 
  670         int ifid = clickInstance->GetInterfaceId (ifname);
 
  674             retval = simstrlcpy (buf, len, clickInstance->GetIpPrefixFromInterfaceId (ifid));
 
  681         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" SIMCLICK_IPPREFIX_FROM_NAME: " << ifname << 
" " << buf << 
" " << len);
 
  685     case SIMCLICK_MACADDR_FROM_NAME:
 
  687         const char *ifname = va_arg (val, 
const char *);
 
  688         char *buf = va_arg (val, 
char *);
 
  689         int len = va_arg (val, 
int);
 
  690         int ifid = clickInstance->GetInterfaceId (ifname);
 
  694             retval = simstrlcpy (buf, len, clickInstance->GetMacAddressFromInterfaceId (ifid));
 
  701         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" SIMCLICK_MACADDR_FROM_NAME: " << ifname << 
" " << buf << 
" " << len);
 
  705     case SIMCLICK_SCHEDULE:
 
  707         const struct timeval *when = va_arg (val, 
const struct timeval *);
 
  709         clickInstance->HandleScheduleFromClick (when);
 
  712         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" SIMCLICK_SCHEDULE at " << when->tv_sec << 
"s and " << when->tv_usec << 
"usecs.");
 
  717     case SIMCLICK_GET_NODE_NAME:
 
  719         char *buf = va_arg (val, 
char *);
 
  720         int len = va_arg (val, 
int);
 
  721         retval = simstrlcpy (buf, len, clickInstance->GetNodeName ());
 
  723         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" SIMCLICK_GET_NODE_NAME: " << buf << 
" " << len);
 
  727     case SIMCLICK_IF_PROMISC:
 
  729         int ifid = va_arg(val, 
int);
 
  730         clickInstance->SetPromisc (ifid);
 
  737     case SIMCLICK_IF_READY:
 
  739         int ifid = va_arg (val, 
int); 
 
  742         retval = clickInstance->IsInterfaceReady (ifid);
 
  751         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" Received a call for SIMCLICK_TRACE");
 
  755     case SIMCLICK_GET_NODE_ID:
 
  758         NS_LOG_DEBUG (clickInstance->GetNodeName () << 
" Received a call for SIMCLICK_GET_NODE_ID");
 
  762     case SIMCLICK_GET_RANDOM_INT:
 
  764         uint32_t *randomValue = va_arg (val, uint32_t *);
 
  765         uint32_t maxValue = va_arg (val, uint32_t);
 
  767         *randomValue = 
static_cast<uint32_t
> (clickInstance->GetRandomVariable ()->GetValue (0.0, static_cast<double> (maxValue) + 1.0));
 
  773     case SIMCLICK_GET_DEFINES:
 
  775         char *buf = va_arg (val, 
char *);
 
  776         size_t *size = va_arg (val, 
size_t *);
 
  777         uint32_t required = 0;
 
  785         std::map<std::string, std::string> defines = clickInstance->GetDefines ();
 
  786         std::map<std::string, std::string>::const_iterator it = defines.begin ();
 
  787         while (it != defines.end ())
 
  789             size_t available = *size - required;
 
  790             if (it->first.length() + it->second.length() + 2 <= available)
 
  792                 simstrlcpy(buf + required, available, it->first);
 
  793                 required += it->first.length() + 1;
 
  794                 available -= it->first.length() + 1;
 
  795                 simstrlcpy(buf + required, available, it->second);
 
  796                 required += it->second.length() + 1;
 
  800                 required += it->first.length() + it->second.length() + 2;
 
  804         if (required > *size)
 
void SetIpv4(const char *deviceName, const char *ip, const char *netmask)
 
smart pointer class similar to boost::intrusive_ptr 
 
#define NS_LOG_FUNCTION(parameters)
 
#define NS_ASSERT(condition)
 
#define NS_LOG_COMPONENT_DEFINE(name)
 
int64_t GetFemtoSeconds(void) const 
 
#define NS_FATAL_ERROR(msg)
fatal error handling 
 
double GetSeconds(void) const 
 
int64_t GetMicroSeconds(void) const 
 
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
 
int64_t GetNanoSeconds(void) const 
 
int64_t GetPicoSeconds(void) const 
 
Time Now(void)
create an ns3::Time instance which contains the current simulation time. 
 
#define NS_LOG_DEBUG(msg)
 
static TypeId GetTypeId(void)
 
TypeId SetParent(TypeId tid)