A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ipv4-click-routing.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Lalith Suresh
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: Lalith Suresh <suresh.lalith@gmail.com>
19  */
20 
21 
22 #ifdef NS3_CLICK
23 
24 #include "ns3/node.h"
25 #include "ns3/simulator.h"
26 #include "ns3/log.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"
31 
32 #include "ipv4-click-routing.h"
33 #include <string>
34 #include <map>
35 
36 #include <cstdlib>
37 #include <cstdarg>
38 
39 NS_LOG_COMPONENT_DEFINE ("Ipv4ClickRouting");
40 
41 namespace ns3 {
42 
43 // Values from nsclick ExtRouter implementation
44 #define INTERFACE_ID_KERNELTAP 0
45 #define INTERFACE_ID_FIRST 1
46 #define INTERFACE_ID_FIRST_DROP 33
47 
48 NS_OBJECT_ENSURE_REGISTERED (Ipv4ClickRouting);
49 
50 std::map < simclick_node_t *, Ptr<Ipv4ClickRouting> > Ipv4ClickRouting::m_clickInstanceFromSimNode;
51 
52 TypeId
53 Ipv4ClickRouting::GetTypeId (void)
54 {
55  static TypeId tid = TypeId ("ns3::Ipv4ClickRouting")
56  .SetParent<Ipv4RoutingProtocol> ()
57  .AddConstructor<Ipv4ClickRouting> ()
58  ;
59 
60  return tid;
61 }
62 
63 Ipv4ClickRouting::Ipv4ClickRouting ()
64  : m_nonDefaultName (false),
65  m_ipv4 (0)
66 {
67  m_random = CreateObject<UniformRandomVariable> ();
68  m_simNode = new simclick_node_t;
69  timerclear (&m_simNode->curtime);
70 
71  AddSimNodeToClickMapping ();
72 }
73 
74 Ipv4ClickRouting::~Ipv4ClickRouting ()
75 {
76 }
77 
78 void
80 {
81  uint32_t id = m_ipv4->GetObject<Node> ()->GetId ();
82 
83  if (!m_nonDefaultName)
84  {
85  std::stringstream name;
86  name << "Node" << id;
87  m_nodeName = name.str ();
88  }
89 
90  NS_ASSERT (m_clickFile.length () > 0);
91 
92  // Even though simclick_click_create() will halt programme execution
93  // if it is unable to initialise a Click router, we play safe
94  if (simclick_click_create (m_simNode, m_clickFile.c_str ()) >= 0)
95  {
96  NS_LOG_DEBUG (m_nodeName << " has initialised a Click Router");
97  m_clickInitialised = true;
98  }
99  else
100  {
101  NS_LOG_DEBUG ("Click Router Initialisation failed for " << m_nodeName);
102  m_clickInitialised = false;
103  }
104 
105  NS_ASSERT (m_clickInitialised == true);
106  simclick_click_run (m_simNode);
107 }
108 
109 void
110 Ipv4ClickRouting::SetIpv4 (Ptr<Ipv4> ipv4)
111 {
112  m_ipv4 = ipv4;
113 }
114 
115 Ptr<UniformRandomVariable>
116 Ipv4ClickRouting::GetRandomVariable (void)
117 {
118  return m_random;
119 }
120 
121 void
123 {
124  if (m_clickInitialised)
125  {
126  simclick_click_kill (m_simNode);
127  }
128  m_ipv4 = 0;
129  delete m_simNode;
131 }
132 
133 void
134 Ipv4ClickRouting::SetClickFile (std::string clickfile)
135 {
136  m_clickFile = clickfile;
137 }
138 
139 void
140 Ipv4ClickRouting::SetDefines (std::map<std::string, std::string> defines)
141 {
142  m_defines = defines;
143 }
144 
145 std::map<std::string, std::string>
146 Ipv4ClickRouting::GetDefines (void)
147 {
148  return m_defines;
149 }
150 
151 void
152 Ipv4ClickRouting::SetClickRoutingTableElement (std::string name)
153 {
154  m_clickRoutingTableElement = name;
155 }
156 
157 void
158 Ipv4ClickRouting::SetNodeName (std::string name)
159 {
160  m_nodeName = name;
161  m_nonDefaultName = true;
162 }
163 
164 std::string
165 Ipv4ClickRouting::GetNodeName ()
166 {
167  return m_nodeName;
168 }
169 
170 int
171 Ipv4ClickRouting::GetInterfaceId (const char *ifname)
172 {
173  int retval = -1;
174 
175  // The below hard coding of interface names follows the
176  // same approach as used in the original nsclick code for
177  // ns-2. The interface names map directly to what is to
178  // be used in the Click configuration files.
179  // Thus eth0 will refer to the first network device of
180  // the node, and is to be named so in the Click graph.
181  // This function is called by Click during the intialisation
182  // phase of the Click graph, during which it tries to map
183  // interface IDs to interface names. The return value
184  // corresponds to the interface ID that Click will use.
185 
186  // Tap/tun devices refer to the kernel devices
187  if (strstr (ifname, "tap") || strstr (ifname, "tun"))
188  {
189  retval = 0;
190  }
191  else if (const char *devname = strstr (ifname, "eth"))
192  {
193  while (*devname && !isdigit ((unsigned char) *devname))
194  {
195  devname++;
196  }
197 
198  if (*devname)
199  {
200  retval = atoi (devname) + INTERFACE_ID_FIRST;
201  }
202  }
203  else if (const char *devname = strstr (ifname, "drop"))
204  {
205  while (*devname && !isdigit ((unsigned char) *devname))
206  {
207  devname++;
208  }
209  if (*devname)
210  {
211  retval = atoi (devname) + INTERFACE_ID_FIRST_DROP;
212  }
213  }
214 
215  // This protects against a possible inconsistency of having
216  // more interfaces defined in the Click graph
217  // for a Click node than are defined for it in
218  // the simulation script
219  if (retval >= (int) m_ipv4->GetNInterfaces ())
220  {
221  return -1;
222  }
223 
224  return retval;
225 }
226 
227 bool
228 Ipv4ClickRouting::IsInterfaceReady (int ifid)
229 {
230  if (ifid >= 0 && ifid < (int) m_ipv4->GetNInterfaces ())
231  {
232  return true;
233  }
234  else
235  {
236  return false;
237  }
238 }
239 
240 std::string
241 Ipv4ClickRouting::GetIpAddressFromInterfaceId (int ifid)
242 {
243  std::stringstream addr;
244  m_ipv4->GetAddress (ifid, 0).GetLocal ().Print (addr);
245 
246  return addr.str ();
247 }
248 
249 std::string
250 Ipv4ClickRouting::GetIpPrefixFromInterfaceId (int ifid)
251 {
252  std::stringstream addr;
253  m_ipv4->GetAddress (ifid, 0).GetMask ().Print (addr);
254 
255  return addr.str ();
256 }
257 
258 std::string
259 Ipv4ClickRouting::GetMacAddressFromInterfaceId (int ifid)
260 {
261  std::stringstream addr;
262 
263  Ptr<NetDevice> device = m_ipv4->GetNetDevice (ifid);
264  Address devAddr = device->GetAddress ();
265  addr << Mac48Address::ConvertFrom (devAddr);
266 
267  return addr.str ();
268 }
269 
270 void
271 Ipv4ClickRouting::AddSimNodeToClickMapping ()
272 {
273  m_clickInstanceFromSimNode.insert (std::make_pair (m_simNode, this));
274 }
275 
276 Ptr<Ipv4ClickRouting>
277 Ipv4ClickRouting::GetClickInstanceFromSimNode (simclick_node_t *simnode)
278 {
279  return m_clickInstanceFromSimNode[simnode];
280 }
281 
282 struct timeval
283 Ipv4ClickRouting::GetTimevalFromNow () const
284 {
285  struct timeval curtime;
286  uint64_t remainder = 0;
287 
288  curtime.tv_sec = Simulator::Now ().GetSeconds ();
289  curtime.tv_usec = Simulator::Now ().GetMicroSeconds () % 1000000;
290 
291  switch (Simulator::Now ().GetResolution())
292  {
293  case Time::NS:
294  remainder = Simulator::Now ().GetNanoSeconds () % 1000;
295  break;
296  case Time::PS:
297  remainder = Simulator::Now ().GetPicoSeconds () % 1000000;
298  break;
299  case Time::FS:
300  remainder = Simulator::Now ().GetFemtoSeconds () % 1000000000;
301  break;
302  default:
303  break;
304  }
305 
306  if (remainder)
307  {
308  ++curtime.tv_usec;
309  if (curtime.tv_usec == 1000000)
310  {
311  ++curtime.tv_sec;
312  curtime.tv_usec = 0;
313  }
314  }
315 
316  return curtime;
317 }
318 
319 void
320 Ipv4ClickRouting::RunClickEvent ()
321 {
322  m_simNode->curtime = GetTimevalFromNow ();
323 
324  NS_LOG_DEBUG ("RunClickEvent at " << m_simNode->curtime.tv_sec << " " <<
325  m_simNode->curtime.tv_usec << " " << Simulator::Now ());
326  simclick_click_run (m_simNode);
327 }
328 
329 void
330 Ipv4ClickRouting::HandleScheduleFromClick (const struct timeval *when)
331 {
332  NS_LOG_DEBUG ("HandleScheduleFromClick at " << when->tv_sec << " " << when->tv_usec << " " << Simulator::Now ());
333 
334  Time simtime = Time::FromInteger(when->tv_sec, Time::S) + Time::FromInteger(when->tv_usec, Time::US);
335  Time simdelay = simtime - Simulator::Now();
336 
337  Simulator::Schedule (simdelay, &Ipv4ClickRouting::RunClickEvent, this);
338 }
339 
340 void
341 Ipv4ClickRouting::HandlePacketFromClick (int ifid, int ptype, const unsigned char* data, int len)
342 {
343  NS_LOG_DEBUG ("HandlePacketFromClick");
344 
345  // Figure out packet's destination here:
346  // If ifid == 0, then the packet's going up
347  // else, the packet's going down
348  if (ifid == 0)
349  {
350  NS_LOG_DEBUG ("Incoming packet from tap0. Sending Packet up the stack.");
351  Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
352 
353  Ptr<Packet> p = Create<Packet> (data, len);
354 
355  Ipv4Header ipHeader;
356  p->RemoveHeader (ipHeader);
357 
358  ipv4l3->LocalDeliver (p, ipHeader, (uint32_t) ifid);
359  }
360  else if (ifid)
361  {
362  NS_LOG_DEBUG ("Incoming packet from eth" << ifid - 1 << " of type " << ptype << ". Sending packet down the stack.");
363 
364  Ptr<Packet> p = Create<Packet> (data, len);
365 
366  DynamicCast<Ipv4L3ClickProtocol> (m_ipv4)->SendDown (p, ifid);
367  }
368 }
369 
370 void
371 Ipv4ClickRouting::SendPacketToClick (int ifid, int ptype, const unsigned char* data, int len)
372 {
373  NS_LOG_FUNCTION (this << ifid);
374  m_simNode->curtime = GetTimevalFromNow ();
375 
376  // Since packets in ns-3 don't have global Packet ID's and Flow ID's, we
377  // feed dummy values into pinfo. This avoids the need to make changes in the Click code
378  simclick_simpacketinfo pinfo;
379  pinfo.id = 0;
380  pinfo.fid = 0;
381 
382  simclick_click_send (m_simNode,ifid,ptype,data,len,&pinfo);
383 }
384 
385 void
386 Ipv4ClickRouting::Send (Ptr<Packet> p, Ipv4Address src, Ipv4Address dst)
387 {
388  uint32_t ifid;
389 
390  // Find out which interface holds the src address of the packet...
391  for (ifid = 0; ifid < m_ipv4->GetNInterfaces (); ifid++)
392  {
393  Ipv4Address addr = m_ipv4->GetAddress (ifid, 0).GetLocal ();
394 
395  if (addr == src)
396  {
397  break;
398  }
399  }
400 
401  int len = p->GetSize ();
402  uint8_t *buf = new uint8_t [len];
403  p->CopyData (buf, len);
404 
405  // ... and send the packet on the corresponding Click interface.
406  SendPacketToClick (0, SIMCLICK_PTYPE_IP, buf, len);
407 
408  delete [] buf;
409 }
410 
411 void
412 Ipv4ClickRouting::Receive (Ptr<Packet> p, Mac48Address receiverAddr, Mac48Address dest)
413 {
414  NS_LOG_FUNCTION (this << p << receiverAddr << dest);
415 
416  uint32_t ifid;
417 
418  // Find out which device this packet was received from...
419  for (ifid = 0; ifid < m_ipv4->GetNInterfaces (); ifid++)
420  {
421  Ptr<NetDevice> device = m_ipv4->GetNetDevice (ifid);
422 
423  if (Mac48Address::ConvertFrom (device->GetAddress ()) == receiverAddr)
424  {
425  break;
426  }
427  }
428 
429  int len = p->GetSize ();
430  uint8_t *buf = new uint8_t [len];
431  p->CopyData (buf, len);
432 
433  // ... and send the packet to the corresponding Click interface
434  SendPacketToClick (ifid, SIMCLICK_PTYPE_ETHER, buf, len);
435 
436  delete [] buf;
437 }
438 
439 std::string
440 Ipv4ClickRouting::ReadHandler (std::string elementName, std::string handlerName)
441 {
442  char *handle = simclick_click_read_handler (m_simNode, elementName.c_str (), handlerName.c_str (), 0, 0);
443  std::string ret (handle);
444 
445  // This is required because Click does not free
446  // the memory allocated to the return string
447  // from simclick_click_read_handler()
448  free(handle);
449 
450  return ret;
451 }
452 
453 int
454 Ipv4ClickRouting::WriteHandler (std::string elementName, std::string handlerName, std::string writeString)
455 {
456  int r = simclick_click_write_handler (m_simNode, elementName.c_str (), handlerName.c_str (), writeString.c_str ());
457 
458  // Note: There are probably use-cases for returning
459  // a write handler's error code, so don't assert.
460  // For example, the 'add' handler for IPRouteTable
461  // type elements fails if the route to be added
462  // already exists.
463 
464  return r;
465 }
466 
467 void
468 Ipv4ClickRouting::SetPromisc (int ifid)
469 {
470  Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
471  NS_ASSERT(ipv4l3);
472  ipv4l3->SetPromisc (ifid);
473 }
474 
475 Ptr<Ipv4Route>
476 Ipv4ClickRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
477 {
478  Ptr<Ipv4Route> rtentry;
479 
480  std::stringstream addr;
481  addr << "lookup ";
482  header.GetDestination ().Print (addr);
483  // Probe the Click Routing Table for the required IP
484  // This returns a string of the form "InterfaceID GatewayAddr"
485  std::string s = ReadHandler (m_clickRoutingTableElement, addr.str ());
486 
487  int pos = s.find (" ");
488 
489  int interfaceId = atoi (s.substr (0, pos).c_str ());
490  Ipv4Address destination (s.substr (pos + 1).c_str ());
491 
492  if (interfaceId != -1)
493  {
494  rtentry = Create<Ipv4Route> ();
495  rtentry->SetDestination (header.GetDestination ());
496  // the source address is the interface address that matches
497  // the destination address (when multiple are present on the
498  // outgoing interface, one is selected via scoping rules)
499  NS_ASSERT (m_ipv4);
500  uint32_t numOifAddresses = m_ipv4->GetNAddresses (interfaceId);
501  NS_ASSERT (numOifAddresses > 0);
502  Ipv4InterfaceAddress ifAddr;
503  if (numOifAddresses == 1)
504  {
505  ifAddr = m_ipv4->GetAddress (interfaceId, 0);
506  }
507  else
508  {
509  NS_FATAL_ERROR ("XXX Not implemented yet: IP aliasing and Click");
510  }
511  rtentry->SetSource (ifAddr.GetLocal ());
512  rtentry->SetGateway (destination);
513  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceId));
514  sockerr = Socket::ERROR_NOTERROR;
515  NS_LOG_DEBUG ("Found route to " << rtentry->GetDestination ()
516  << " via nh " << rtentry->GetGateway ()
517  << " with source addr " << rtentry->GetSource ()
518  << " and output dev " << rtentry->GetOutputDevice ());
519  }
520  else
521  {
522  NS_LOG_DEBUG ("Click node " << m_nodeName
523  << ": RouteOutput for dest=" << header.GetDestination ()
524  << " No route to host");
525  sockerr = Socket::ERROR_NOROUTETOHOST;
526  }
527 
528  return rtentry;
529 }
530 
531 // This method should never be called since Click handles
532 // forwarding directly
533 bool
534 Ipv4ClickRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header,
535  Ptr<const NetDevice> idev, UnicastForwardCallback ucb,
536  MulticastForwardCallback mcb, LocalDeliverCallback lcb,
537  ErrorCallback ecb)
538 {
539  NS_FATAL_ERROR ("Click router does not have a RouteInput() interface!");
540  return false;
541 }
542 
543 void
544 Ipv4ClickRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
545 {
546 }
547 
548 void
550 {
551 }
552 
553 void
555 {
556 }
557 
558 void
559 Ipv4ClickRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address)
560 {
561 }
562 
563 void
564 Ipv4ClickRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address)
565 {
566 }
567 
568 
569 } // namespace ns3
570 
571 static int simstrlcpy (char *buf, int len, const std::string &s)
572 {
573  if (len)
574  {
575  len--;
576 
577  if ((unsigned) len > s.length ())
578  {
579  len = s.length ();
580  }
581 
582  s.copy (buf, len);
583  buf[len] = '\0';
584  }
585  return 0;
586 }
587 
588 // Sends a Packet from Click to the Simulator: Defined in simclick.h. Click
589 // calls these methods.
590 int simclick_sim_send (simclick_node_t *simnode,
591  int ifid, int type, const unsigned char* data, int len,
592  simclick_simpacketinfo *pinfo)
593 {
594  NS_LOG_DEBUG ("simclick_sim_send called at " << ns3::Simulator::Now ().GetSeconds () << ": " << ifid << " " << type << " " << data << " " << len);
595 
596  if (simnode == NULL)
597  {
598  return -1;
599  }
600 
601  ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance = ns3::Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode);
602 
603  clickInstance->HandlePacketFromClick (ifid, type, data, len);
604 
605  return 0;
606 }
607 
608 // Click Service Methods: Defined in simclick.h
609 int simclick_sim_command (simclick_node_t *simnode, int cmd, ...)
610 {
611  va_list val;
612  va_start (val, cmd);
613 
614  int retval = 0;
615 
616  ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance = ns3::Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode);
617  switch (cmd)
618  {
619  case SIMCLICK_VERSION:
620  {
621  retval = 0;
622  break;
623  }
624 
625  case SIMCLICK_SUPPORTS:
626  {
627  int othercmd = va_arg (val, int);
628  retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
629  break;
630  }
631 
632  case SIMCLICK_IFID_FROM_NAME:
633  {
634  const char *ifname = va_arg (val, const char *);
635 
636  retval = clickInstance->GetInterfaceId (ifname);
637 
638  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IFID_FROM_NAME: " << ifname << " " << retval);
639  break;
640  }
641 
642  case SIMCLICK_IPADDR_FROM_NAME:
643  {
644  const char *ifname = va_arg (val, const char *);
645  char *buf = va_arg (val, char *);
646  int len = va_arg (val, int);
647 
648  int ifid = clickInstance->GetInterfaceId (ifname);
649 
650  if (ifid >= 0)
651  {
652  retval = simstrlcpy (buf, len, clickInstance->GetIpAddressFromInterfaceId (ifid));
653  }
654  else
655  {
656  retval = -1;
657  }
658 
659  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
660  break;
661  }
662 
663  case SIMCLICK_IPPREFIX_FROM_NAME:
664  {
665  const char *ifname = va_arg (val, const char *);
666  char *buf = va_arg (val, char *);
667  int len = va_arg (val, int);
668 
669  int ifid = clickInstance->GetInterfaceId (ifname);
670 
671  if (ifid >= 0)
672  {
673  retval = simstrlcpy (buf, len, clickInstance->GetIpPrefixFromInterfaceId (ifid));
674  }
675  else
676  {
677  retval = -1;
678  }
679 
680  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPPREFIX_FROM_NAME: " << ifname << " " << buf << " " << len);
681  break;
682  }
683 
684  case SIMCLICK_MACADDR_FROM_NAME:
685  {
686  const char *ifname = va_arg (val, const char *);
687  char *buf = va_arg (val, char *);
688  int len = va_arg (val, int);
689  int ifid = clickInstance->GetInterfaceId (ifname);
690 
691  if (ifid >= 0)
692  {
693  retval = simstrlcpy (buf, len, clickInstance->GetMacAddressFromInterfaceId (ifid));
694  }
695  else
696  {
697  retval = -1;
698  }
699 
700  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_MACADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
701  break;
702  }
703 
704  case SIMCLICK_SCHEDULE:
705  {
706  const struct timeval *when = va_arg (val, const struct timeval *);
707 
708  clickInstance->HandleScheduleFromClick (when);
709 
710  retval = 0;
711  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_SCHEDULE at " << when->tv_sec << "s and " << when->tv_usec << "usecs.");
712 
713  break;
714  }
715 
716  case SIMCLICK_GET_NODE_NAME:
717  {
718  char *buf = va_arg (val, char *);
719  int len = va_arg (val, int);
720  retval = simstrlcpy (buf, len, clickInstance->GetNodeName ());
721 
722  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_GET_NODE_NAME: " << buf << " " << len);
723  break;
724  }
725 
726  case SIMCLICK_IF_PROMISC:
727  {
728  int ifid = va_arg(val, int);
729  clickInstance->SetPromisc (ifid);
730 
731  retval = 0;
732  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_PROMISC: " << ifid << " " << ns3::Simulator::Now ());
733  break;
734  }
735 
736  case SIMCLICK_IF_READY:
737  {
738  int ifid = va_arg (val, int); // Commented out so that optimized build works
739 
740  // We're not using a ClickQueue, so we're always ready (for the timebeing)
741  retval = clickInstance->IsInterfaceReady (ifid);
742 
743  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_READY: " << ifid << " " << ns3::Simulator::Now ());
744  break;
745  }
746 
747  case SIMCLICK_TRACE:
748  {
749  // Used only for tracing
750  NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_TRACE");
751  break;
752  }
753 
754  case SIMCLICK_GET_NODE_ID:
755  {
756  // Used only for tracing
757  NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_GET_NODE_ID");
758  break;
759  }
760 
761  case SIMCLICK_GET_RANDOM_INT:
762  {
763  uint32_t *randomValue = va_arg (val, uint32_t *);
764  uint32_t maxValue = va_arg (val, uint32_t);
765 
766  *randomValue = static_cast<uint32_t> (clickInstance->GetRandomVariable ()->GetValue (0.0, static_cast<double> (maxValue) + 1.0));
767  retval = 0;
768  NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_RANDOM: " << *randomValue << " " << maxValue << " " << ns3::Simulator::Now ());
769  break;
770  }
771 
772  case SIMCLICK_GET_DEFINES:
773  {
774  char *buf = va_arg (val, char *);
775  size_t *size = va_arg (val, size_t *);
776  uint32_t required = 0;
777 
778  // Try to fill the buffer with up to size bytes.
779  // If this is not enough space, write the required buffer size into
780  // the size variable and return an error code.
781  // Otherwise return the bytes actually writte into the buffer in size.
782 
783  // Append key/value pair, seperated by \0.
784  std::map<std::string, std::string> defines = clickInstance->GetDefines ();
785  std::map<std::string, std::string>::const_iterator it = defines.begin ();
786  while (it != defines.end ())
787  {
788  size_t available = *size - required;
789  if (it->first.length() + it->second.length() + 2 <= available)
790  {
791  simstrlcpy(buf + required, available, it->first);
792  required += it->first.length() + 1;
793  available -= it->first.length() + 1;
794  simstrlcpy(buf + required, available, it->second);
795  required += it->second.length() + 1;
796  }
797  else
798  {
799  required += it->first.length() + it->second.length() + 2;
800  }
801  it++;
802  }
803  if (required > *size)
804  {
805  retval = -1;
806  }
807  else
808  {
809  retval = 0;
810  }
811  *size = required;
812  }
813  }
814  return retval;
815 }
816 
817 #endif // NS3_CLICK
virtual void SetIpv4(Ptr< Ipv4 > ipv4)=0
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
virtual void NotifyInterfaceUp(uint32_t interface)=0
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual void DoDispose(void)
Definition: object.cc:335
int64_t GetFemtoSeconds(void) const
Definition: nstime.h:303
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
double GetSeconds(void) const
Definition: nstime.h:262
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
int64_t GetMicroSeconds(void) const
Definition: nstime.h:279
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)=0
Route an input packet (to be forwarded or locally delivered)
static Mac48Address ConvertFrom(const Address &address)
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const =0
Print the Routing Table entries.
static Time Now(void)
Definition: simulator.cc:179
int64_t GetNanoSeconds(void) const
Definition: nstime.h:287
static Time FromInteger(uint64_t value, enum Unit timeUnit)
Definition: nstime.h:347
int64_t GetPicoSeconds(void) const
Definition: nstime.h:295
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)=0
Query routing cache for an existing route, for an outbound packet.
virtual void NotifyInterfaceDown(uint32_t interface)=0
virtual void DoInitialize(void)
Definition: object.cc:342
void SetDestination(Ipv4Address dest)
Definition: ipv4-route.cc:35