A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-click-routing.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Lalith Suresh
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Lalith Suresh <suresh.lalith@gmail.com>
18 */
19
20#include "ipv4-click-routing.h"
21
23
24#include "ns3/ipv4-interface.h"
25#include "ns3/log.h"
26#include "ns3/mac48-address.h"
27#include "ns3/node.h"
28#include "ns3/random-variable-stream.h"
29#include "ns3/simulator.h"
30
31#include <click/simclick.h>
32#include <cstdarg>
33#include <cstdlib>
34#include <map>
35#include <string>
36
37namespace ns3
38{
39
40NS_LOG_COMPONENT_DEFINE("Ipv4ClickRouting");
41
42// Values from nsclick ExtRouter implementation
43#define INTERFACE_ID_KERNELTAP 0
44#define INTERFACE_ID_FIRST 1
45#define INTERFACE_ID_FIRST_DROP 33
46
47NS_OBJECT_ENSURE_REGISTERED(Ipv4ClickRouting);
48
49std::map<simclick_node_t*, Ptr<Ipv4ClickRouting>> Ipv4ClickRouting::m_clickInstanceFromSimNode;
50
51TypeId
53{
54 static TypeId tid = TypeId("ns3::Ipv4ClickRouting")
56 .AddConstructor<Ipv4ClickRouting>()
57 .SetGroupName("Click");
58
59 return tid;
60}
61
63 : m_nonDefaultName(false),
64 m_ipv4(nullptr)
65{
66 m_random = CreateObject<UniformRandomVariable>();
68 timerclear(&m_simNode->curtime);
69
71}
72
74{
75}
76
77void
79{
80 uint32_t id = m_ipv4->GetObject<Node>()->GetId();
81
83 {
84 std::stringstream name;
85 name << "Node" << id;
86 m_nodeName = name.str();
87 }
88
89 NS_ASSERT(!m_clickFile.empty());
90
91 // Even though simclick_click_create() will halt programme execution
92 // if it is unable to initialise a Click router, we play safe
93 if (simclick_click_create(m_simNode, m_clickFile.c_str()) >= 0)
94 {
95 NS_LOG_DEBUG(m_nodeName << " has initialised a Click Router");
96 m_clickInitialised = true;
97 }
98 else
99 {
100 NS_LOG_DEBUG("Click Router Initialisation failed for " << m_nodeName);
101 m_clickInitialised = false;
102 }
103
105 simclick_click_run(m_simNode);
106}
107
108void
110{
111 m_ipv4 = ipv4;
112}
113
116{
117 return m_random;
118}
119
120void
122{
124 {
125 simclick_click_kill(m_simNode);
126 }
127 m_ipv4 = nullptr;
128 delete m_simNode;
130}
131
132void
133Ipv4ClickRouting::SetClickFile(std::string clickfile)
134{
135 m_clickFile = clickfile;
136}
137
138void
139Ipv4ClickRouting::SetDefines(std::map<std::string, std::string> defines)
140{
141 m_defines = defines;
142}
143
144std::map<std::string, std::string>
146{
147 return m_defines;
148}
149
150void
152{
154}
155
156void
158{
159 m_nodeName = name;
160 m_nonDefaultName = true;
161}
162
163std::string
165{
166 return m_nodeName;
167}
168
169int
171{
172 int retval = -1;
173
174 // The below hard coding of interface names follows the
175 // same approach as used in the original nsclick code for
176 // ns-2. The interface names map directly to what is to
177 // be used in the Click configuration files.
178 // Thus eth0 will refer to the first network device of
179 // the node, and is to be named so in the Click graph.
180 // This function is called by Click during the initialisation
181 // phase of the Click graph, during which it tries to map
182 // interface IDs to interface names. The return value
183 // corresponds to the interface ID that Click will use.
184
185 // Tap/tun devices refer to the kernel devices
186 if (strstr(ifname, "tap") || strstr(ifname, "tun"))
187 {
188 retval = 0;
189 }
190 else if (const char* devname = strstr(ifname, "eth"))
191 {
192 while (*devname && !isdigit((unsigned char)*devname))
193 {
194 devname++;
195 }
196
197 if (*devname)
198 {
199 retval = atoi(devname) + INTERFACE_ID_FIRST;
200 }
201 }
202 else if (const char* devname = strstr(ifname, "drop"))
203 {
204 while (*devname && !isdigit((unsigned char)*devname))
205 {
206 devname++;
207 }
208 if (*devname)
209 {
210 retval = atoi(devname) + INTERFACE_ID_FIRST_DROP;
211 }
212 }
213
214 // This protects against a possible inconsistency of having
215 // more interfaces defined in the Click graph
216 // for a Click node than are defined for it in
217 // the simulation script
218 if (retval >= (int)m_ipv4->GetNInterfaces())
219 {
220 return -1;
221 }
222
223 return retval;
224}
225
226bool
228{
229 return ifid >= 0 && ifid < static_cast<int>(m_ipv4->GetNInterfaces());
230}
231
232std::string
234{
235 std::stringstream addr;
236 m_ipv4->GetAddress(ifid, 0).GetLocal().Print(addr);
237
238 return addr.str();
239}
240
241std::string
243{
244 std::stringstream addr;
245 m_ipv4->GetAddress(ifid, 0).GetMask().Print(addr);
246
247 return addr.str();
248}
249
250std::string
252{
253 std::stringstream addr;
254
255 Ptr<NetDevice> device = m_ipv4->GetNetDevice(ifid);
256 Address devAddr = device->GetAddress();
257 addr << Mac48Address::ConvertFrom(devAddr);
258
259 return addr.str();
260}
261
262void
264{
265 m_clickInstanceFromSimNode.insert(std::make_pair(m_simNode, this));
266}
267
270{
271 return m_clickInstanceFromSimNode[simnode];
272}
273
274struct timeval
275Ipv4ClickRouting::GetTimevalFromNow() const
276{
277 struct timeval curtime;
278 uint64_t remainder = 0;
279
280 Time now = Simulator::Now();
281
282 curtime.tv_sec = now.GetSeconds();
283 curtime.tv_usec = now.GetMicroSeconds() % 1000000;
284
285 switch (Time::GetResolution())
286 {
287 case Time::NS:
288 remainder = now.GetNanoSeconds() % 1000;
289 break;
290 case Time::PS:
291 remainder = now.GetPicoSeconds() % 1000000;
292 break;
293 case Time::FS:
294 remainder = now.GetFemtoSeconds() % 1000000000;
295 break;
296 default:
297 break;
298 }
299
300 if (remainder)
301 {
302 ++curtime.tv_usec;
303 if (curtime.tv_usec == 1000000)
304 {
305 ++curtime.tv_sec;
306 curtime.tv_usec = 0;
307 }
308 }
309
310 return curtime;
311}
312
313void
315{
316 m_simNode->curtime = GetTimevalFromNow();
317
318 NS_LOG_DEBUG("RunClickEvent at " << m_simNode->curtime.tv_sec << " "
319 << m_simNode->curtime.tv_usec << " " << Simulator::Now());
320 simclick_click_run(m_simNode);
321}
322
323void
325{
326 NS_LOG_DEBUG("HandleScheduleFromClick at " << when->tv_sec << " " << when->tv_usec << " "
327 << Simulator::Now());
328
329 Time simtime =
330 Time::FromInteger(when->tv_sec, Time::S) + Time::FromInteger(when->tv_usec, Time::US);
331 Time simdelay = simtime - Simulator::Now();
332
334}
335
336void
337Ipv4ClickRouting::HandlePacketFromClick(int ifid, int ptype, const unsigned char* data, int len)
338{
339 NS_LOG_DEBUG("HandlePacketFromClick");
340
341 // Figure out packet's destination here:
342 // If ifid == 0, then the packet's going up
343 // else, the packet's going down
344 if (ifid == 0)
345 {
346 NS_LOG_DEBUG("Incoming packet from tap0. Sending Packet up the stack.");
347 Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol>(m_ipv4);
348
349 Ptr<Packet> p = Create<Packet>(data, len);
350
351 Ipv4Header ipHeader;
352 p->RemoveHeader(ipHeader);
353
354 ipv4l3->LocalDeliver(p, ipHeader, (uint32_t)ifid);
355 }
356 else if (ifid)
357 {
358 NS_LOG_DEBUG("Incoming packet from eth" << ifid - 1 << " of type " << ptype
359 << ". Sending packet down the stack.");
360
361 Ptr<Packet> p = Create<Packet>(data, len);
362
363 DynamicCast<Ipv4L3ClickProtocol>(m_ipv4)->SendDown(p, ifid);
364 }
365}
366
367void
368Ipv4ClickRouting::SendPacketToClick(int ifid, int ptype, const unsigned char* data, int len)
369{
370 NS_LOG_FUNCTION(this << ifid);
371 m_simNode->curtime = GetTimevalFromNow();
372
373 // Since packets in ns-3 don't have global Packet ID's and Flow ID's, we
374 // feed dummy values into pinfo. This avoids the need to make changes in the Click code
375 simclick_simpacketinfo pinfo;
376 pinfo.id = 0;
377 pinfo.fid = 0;
378
379 simclick_click_send(m_simNode, ifid, ptype, data, len, &pinfo);
380}
381
382void
384{
385 uint32_t ifid;
386
387 // Find out which interface holds the src address of the packet...
388 for (ifid = 0; ifid < m_ipv4->GetNInterfaces(); ifid++)
389 {
390 Ipv4Address addr = m_ipv4->GetAddress(ifid, 0).GetLocal();
391
392 if (addr == src)
393 {
394 break;
395 }
396 }
397
398 int len = p->GetSize();
399 auto buf = new uint8_t[len];
400 p->CopyData(buf, len);
401
402 // ... and send the packet on the corresponding Click interface.
403 SendPacketToClick(0, SIMCLICK_PTYPE_IP, buf, len);
404
405 delete[] buf;
406}
407
408void
410{
411 NS_LOG_FUNCTION(this << p << receiverAddr << dest);
412
413 uint32_t ifid;
414
415 // Find out which device this packet was received from...
416 for (ifid = 0; ifid < m_ipv4->GetNInterfaces(); ifid++)
417 {
418 Ptr<NetDevice> device = m_ipv4->GetNetDevice(ifid);
419
420 if (Mac48Address::ConvertFrom(device->GetAddress()) == receiverAddr)
421 {
422 break;
423 }
424 }
425
426 int len = p->GetSize();
427 auto buf = new uint8_t[len];
428 p->CopyData(buf, len);
429
430 // ... and send the packet to the corresponding Click interface
431 SendPacketToClick(ifid, SIMCLICK_PTYPE_ETHER, buf, len);
432
433 delete[] buf;
434}
435
436std::string
437Ipv4ClickRouting::ReadHandler(std::string elementName, std::string handlerName)
438{
439 char* handle = simclick_click_read_handler(m_simNode,
440 elementName.c_str(),
441 handlerName.c_str(),
442 nullptr,
443 nullptr);
444 std::string ret(handle);
445
446 // This is required because Click does not free
447 // the memory allocated to the return string
448 // from simclick_click_read_handler()
449 free(handle);
450
451 return ret;
452}
453
454int
455Ipv4ClickRouting::WriteHandler(std::string elementName,
456 std::string handlerName,
457 std::string writeString)
458{
459 int r = simclick_click_write_handler(m_simNode,
460 elementName.c_str(),
461 handlerName.c_str(),
462 writeString.c_str());
463
464 // Note: There are probably use-cases for returning
465 // a write handler's error code, so don't assert.
466 // For example, the 'add' handler for IPRouteTable
467 // type elements fails if the route to be added
468 // already exists.
469
470 return r;
471}
472
473void
475{
476 Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol>(m_ipv4);
477 NS_ASSERT(ipv4l3);
478 ipv4l3->SetPromisc(ifid);
479}
480
483 const Ipv4Header& header,
484 Ptr<NetDevice> oif,
485 Socket::SocketErrno& sockerr)
486{
487 Ptr<Ipv4Route> rtentry;
488
489 std::stringstream addr;
490 addr << "lookup ";
491 header.GetDestination().Print(addr);
492 // Probe the Click Routing Table for the required IP
493 // This returns a string of the form "InterfaceID GatewayAddr"
494 NS_LOG_DEBUG("Probe click routing table for " << addr.str());
495 std::string s = ReadHandler(m_clickRoutingTableElement, addr.str());
496 NS_LOG_DEBUG("string from click routing table: " << s);
497
498 size_t pos = s.find(' ');
499 Ipv4Address destination;
500 int interfaceId;
501 if (pos == std::string::npos)
502 {
503 // Only an interface ID is found
504 destination = Ipv4Address("0.0.0.0");
505 interfaceId = atoi(s.c_str());
506 NS_LOG_DEBUG("case 1: destination " << destination << " interfaceId " << interfaceId);
507 }
508 else
509 {
510 interfaceId = atoi(s.substr(0, pos).c_str());
511 Ipv4Address destination(s.substr(pos + 1).c_str());
512 NS_LOG_DEBUG("case 2: destination " << destination << " interfaceId " << interfaceId);
513 }
514
515 if (interfaceId != -1)
516 {
517 rtentry = Create<Ipv4Route>();
518 rtentry->SetDestination(header.GetDestination());
519 // the source address is the interface address that matches
520 // the destination address (when multiple are present on the
521 // outgoing interface, one is selected via scoping rules)
523 uint32_t numOifAddresses = m_ipv4->GetNAddresses(interfaceId);
524 NS_ASSERT(numOifAddresses > 0);
526 if (numOifAddresses == 1)
527 {
528 ifAddr = m_ipv4->GetAddress(interfaceId, 0);
529 }
530 else
531 {
532 /** \todo Implement IP aliasing and Click */
533 NS_FATAL_ERROR("XXX Not implemented yet: IP aliasing and Click");
534 }
535 rtentry->SetSource(ifAddr.GetLocal());
536 rtentry->SetGateway(destination);
537 rtentry->SetOutputDevice(m_ipv4->GetNetDevice(interfaceId));
538 sockerr = Socket::ERROR_NOTERROR;
539 NS_LOG_DEBUG("Found route to " << rtentry->GetDestination() << " via nh "
540 << rtentry->GetGateway() << " with source addr "
541 << rtentry->GetSource() << " and output dev "
542 << rtentry->GetOutputDevice());
543 }
544 else
545 {
546 NS_LOG_DEBUG("Click node " << m_nodeName << ": RouteOutput for dest="
547 << header.GetDestination() << " No route to host");
549 }
550
551 return rtentry;
552}
553
554// This method should never be called since Click handles
555// forwarding directly
556bool
558 const Ipv4Header& header,
560 const UnicastForwardCallback& ucb,
561 const MulticastForwardCallback& mcb,
562 const LocalDeliverCallback& lcb,
563 const ErrorCallback& ecb)
564{
565 NS_FATAL_ERROR("Click router does not have a RouteInput() interface!");
566 return false;
567}
568
569void
571{
572 *stream->GetStream() << "\nCLICK Routing table printing is not yet implemented, skipping.\n";
573}
574
575void
577{
578}
579
580void
582{
583}
584
585void
587{
588}
589
590void
592{
593}
594
595} // namespace ns3
596
597using ns3::g_log;
598
599static int
600simstrlcpy(char* buf, int len, const std::string& s)
601{
602 if (len)
603 {
604 len--;
605
606 if ((unsigned)len > s.length())
607 {
608 len = s.length();
609 }
610
611 s.copy(buf, len);
612 buf[len] = '\0';
613 }
614 return 0;
615}
616
617// Sends a Packet from Click to the Simulator: Defined in simclick.h. Click
618// calls these methods.
619int
621 int ifid,
622 int type,
623 const unsigned char* data,
624 int len,
625 simclick_simpacketinfo* pinfo)
626{
627 NS_LOG_DEBUG("simclick_sim_send called at " << ns3::Simulator::Now().As(ns3::Time::S) << ": "
628 << ifid << " " << type << " " << data << " "
629 << len);
630
631 if (!simnode)
632 {
633 return -1;
634 }
635
636 ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance =
638
639 clickInstance->HandlePacketFromClick(ifid, type, data, len);
640
641 return 0;
642}
643
644// Click Service Methods: Defined in simclick.h
645int
647{
648 va_list val;
649 va_start(val, cmd);
650
651 int retval = 0;
652
653 ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance =
655 switch (cmd)
656 {
657 case SIMCLICK_VERSION: {
658 retval = 0;
659 break;
660 }
661
662 case SIMCLICK_SUPPORTS: {
663 int othercmd = va_arg(val, int);
664 retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
665 break;
666 }
667
668 case SIMCLICK_IFID_FROM_NAME: {
669 const char* ifname = va_arg(val, const char*);
670
671 retval = clickInstance->GetInterfaceId(ifname);
672
673 NS_LOG_DEBUG(clickInstance->GetNodeName()
674 << " SIMCLICK_IFID_FROM_NAME: " << ifname << " " << retval);
675 break;
676 }
677
678 case SIMCLICK_IPADDR_FROM_NAME: {
679 const char* ifname = va_arg(val, const char*);
680 char* buf = va_arg(val, char*);
681 int len = va_arg(val, int);
682
683 int ifid = clickInstance->GetInterfaceId(ifname);
684
685 if (ifid >= 0)
686 {
687 retval = simstrlcpy(buf, len, clickInstance->GetIpAddressFromInterfaceId(ifid));
688 }
689 else
690 {
691 retval = -1;
692 }
693
694 NS_LOG_DEBUG(clickInstance->GetNodeName()
695 << " SIMCLICK_IPADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
696 break;
697 }
698
699 case SIMCLICK_IPPREFIX_FROM_NAME: {
700 const char* ifname = va_arg(val, const char*);
701 char* buf = va_arg(val, char*);
702 int len = va_arg(val, int);
703
704 int ifid = clickInstance->GetInterfaceId(ifname);
705
706 if (ifid >= 0)
707 {
708 retval = simstrlcpy(buf, len, clickInstance->GetIpPrefixFromInterfaceId(ifid));
709 }
710 else
711 {
712 retval = -1;
713 }
714
715 NS_LOG_DEBUG(clickInstance->GetNodeName()
716 << " SIMCLICK_IPPREFIX_FROM_NAME: " << ifname << " " << buf << " " << len);
717 break;
718 }
719
720 case SIMCLICK_MACADDR_FROM_NAME: {
721 const char* ifname = va_arg(val, const char*);
722 char* buf = va_arg(val, char*);
723 int len = va_arg(val, int);
724 int ifid = clickInstance->GetInterfaceId(ifname);
725
726 if (ifid >= 0)
727 {
728 retval = simstrlcpy(buf, len, clickInstance->GetMacAddressFromInterfaceId(ifid));
729 }
730 else
731 {
732 retval = -1;
733 }
734
735 NS_LOG_DEBUG(clickInstance->GetNodeName()
736 << " SIMCLICK_MACADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
737 break;
738 }
739
740 case SIMCLICK_SCHEDULE: {
741 const struct timeval* when = va_arg(val, const struct timeval*);
742
743 clickInstance->HandleScheduleFromClick(when);
744
745 retval = 0;
746 NS_LOG_DEBUG(clickInstance->GetNodeName() << " SIMCLICK_SCHEDULE at " << when->tv_sec
747 << "s and " << when->tv_usec << "usecs.");
748
749 break;
750 }
751
752 case SIMCLICK_GET_NODE_NAME: {
753 char* buf = va_arg(val, char*);
754 int len = va_arg(val, int);
755 retval = simstrlcpy(buf, len, clickInstance->GetNodeName());
756
757 NS_LOG_DEBUG(clickInstance->GetNodeName()
758 << " SIMCLICK_GET_NODE_NAME: " << buf << " " << len);
759 break;
760 }
761
762 case SIMCLICK_IF_PROMISC: {
763 int ifid = va_arg(val, int);
764 clickInstance->SetPromisc(ifid);
765
766 retval = 0;
767 NS_LOG_DEBUG(clickInstance->GetNodeName()
768 << " SIMCLICK_IF_PROMISC: " << ifid << " " << ns3::Simulator::Now());
769 break;
770 }
771
772 case SIMCLICK_IF_READY: {
773 int ifid = va_arg(val, int); // Commented out so that optimized build works
774
775 // We're not using a ClickQueue, so we're always ready (for the timebeing)
776 retval = clickInstance->IsInterfaceReady(ifid);
777
778 NS_LOG_DEBUG(clickInstance->GetNodeName()
779 << " SIMCLICK_IF_READY: " << ifid << " " << ns3::Simulator::Now());
780 break;
781 }
782
783 case SIMCLICK_TRACE: {
784 // Used only for tracing
785 NS_LOG_DEBUG(clickInstance->GetNodeName() << " Received a call for SIMCLICK_TRACE");
786 break;
787 }
788
789 case SIMCLICK_GET_NODE_ID: {
790 // Used only for tracing
791 NS_LOG_DEBUG(clickInstance->GetNodeName() << " Received a call for SIMCLICK_GET_NODE_ID");
792 break;
793 }
794
795 case SIMCLICK_GET_RANDOM_INT: {
796 uint32_t* randomValue = va_arg(val, uint32_t*);
797 uint32_t maxValue = va_arg(val, uint32_t);
798
799 *randomValue = static_cast<uint32_t>(
800 clickInstance->GetRandomVariable()->GetValue(0.0, static_cast<double>(maxValue) + 1.0));
801 retval = 0;
802 NS_LOG_DEBUG(clickInstance->GetNodeName() << " SIMCLICK_RANDOM: " << *randomValue << " "
803 << maxValue << " " << ns3::Simulator::Now());
804 break;
805 }
806
807 case SIMCLICK_GET_DEFINES: {
808 char* buf = va_arg(val, char*);
809 size_t* size = va_arg(val, size_t*);
810 uint32_t required = 0;
811
812 // Try to fill the buffer with up to size bytes.
813 // If this is not enough space, write the required buffer size into
814 // the size variable and return an error code.
815 // Otherwise return the bytes actually written into the buffer in size.
816
817 // Append key/value pair, separated by \0.
818 std::map<std::string, std::string> defines = clickInstance->GetDefines();
819
820 for (auto it = defines.begin(); it != defines.end(); it++)
821 {
822 size_t available = *size - required;
823 if (it->first.length() + it->second.length() + 2 <= available)
824 {
825 simstrlcpy(buf + required, available, it->first);
826 required += it->first.length() + 1;
827 available -= it->first.length() + 1;
828 simstrlcpy(buf + required, available, it->second);
829 required += it->second.length() + 1;
830 }
831 else
832 {
833 required += it->first.length() + it->second.length() + 2;
834 }
835 }
836 if (required > *size)
837 {
838 retval = -1;
839 }
840 else
841 {
842 retval = 0;
843 }
844 *size = required;
845 }
846 }
847
848 va_end(val);
849 return retval;
850}
a polymophic address class
Definition: address.h:101
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
void Print(std::ostream &os) const
Print this address to the given output stream.
Class to allow a node to use Click for external routing.
void SetDefines(std::map< std::string, std::string > defines)
Click defines to be used by the node's Click Instance.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
std::string GetIpAddressFromInterfaceId(int ifid)
Provides for SIMCLICK_IPADDR_FROM_NAME.
void RunClickEvent()
This method has to be scheduled every time Click calls SIMCLICK_SCHEDULE.
Ipv4ClickRouting()
Constructor.
simclick_node_t * m_simNode
Pointer to the simclick node.
bool IsInterfaceReady(int ifid)
Provides for SIMCLICK_IF_READY.
int WriteHandler(std::string elementName, std::string handlerName, std::string writeString)
Write Handler interface for a node's Click Elements.
void AddSimNodeToClickMapping()
Used internally in DoInitialize () to Add a mapping to m_clickInstanceFromSimNode mapping.
bool m_clickInitialised
Whether click has been initialized.
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
void SetPromisc(int ifid)
Sets an interface to run on promiscuous mode.
void DoDispose() override
Destructor implementation.
std::string m_nodeName
Name of the node.
void DoInitialize() override
Initialize() implementation.
std::string GetMacAddressFromInterfaceId(int ifid)
Provides for SIMCLICK_MACADDR_FROM_NAME.
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
bool m_nonDefaultName
Whether a non-default name has been set.
void Send(Ptr< Packet > p, Ipv4Address src, Ipv4Address dest)
Allow a higher layer to send data through Click.
Ptr< Ipv4 > m_ipv4
Pointer to the IPv4 object.
void NotifyInterfaceDown(uint32_t interface) override
struct timeval GetTimevalFromNow() const
Get current simulation time as a timeval.
std::map< std::string, std::string > GetDefines()
Provides for SIMCLICK_GET_DEFINES.
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
void SetClickFile(std::string clickfile)
Click configuration file to be used by the node's Click Instance.
Ptr< UniformRandomVariable > m_random
Uniform random variable.
int GetInterfaceId(const char *ifname)
Provides for SIMCLICK_IFID_FROM_NAME.
void SetIpv4(Ptr< Ipv4 > ipv4) override
Set the Ipv4 instance to be used.
std::map< std::string, std::string > m_defines
Defines for .click configuration file parsing.
void SendPacketToClick(int ifid, int type, const unsigned char *data, int len)
Sends a packet to Click.
static Ptr< Ipv4ClickRouting > GetClickInstanceFromSimNode(simclick_node_t *simnode)
Allows the Click service methods, which reside outside Ipv4ClickRouting, to get the required Ipv4Clic...
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
std::string m_clickFile
Name of .click configuration file.
std::string ReadHandler(std::string elementName, std::string handlerName)
Read Handler interface for a node's Click Elements.
static TypeId GetTypeId()
Get type ID.
void HandleScheduleFromClick(const struct timeval *when)
Schedules simclick_click_run to run at the given time.
static std::map< simclick_node_t *, Ptr< Ipv4ClickRouting > > m_clickInstanceFromSimNode
Provide a mapping between the node reference used by Click and the corresponding Ipv4ClickRouting ins...
std::string GetIpPrefixFromInterfaceId(int ifid)
Provides for SIMCLICK_IPPREFIX_FROM_NAME.
void HandlePacketFromClick(int ifid, int type, const unsigned char *data, int len)
Receives a packet from Click.
void SetClickRoutingTableElement(std::string name)
Name of the routing table element being used by Click.
void SetNodeName(std::string name)
Name of the node as to be used by Click.
Ptr< UniformRandomVariable > GetRandomVariable()
Get the uniform random variable.
void Receive(Ptr< Packet > p, Mac48Address receiverAddr, Mac48Address dest)
Allow a lower layer to send data to Click.
std::string GetNodeName()
Provides for SIMCLICK_GET_NODE_NAME.
void NotifyInterfaceUp(uint32_t interface) override
std::string m_clickRoutingTableElement
Name of the routing table element.
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
a class to store IPv4 address information on an interface
Ipv4Address GetLocal() const
Get the local address.
Abstract base class for IPv4 routing protocols.
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address ConvertFrom(const Address &address)
A network Node.
Definition: node.h:57
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:418
int64_t GetFemtoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:428
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
@ US
microsecond
Definition: nstime.h:118
@ S
second
Definition: nstime.h:116
int64_t GetPicoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:423
static Time FromInteger(uint64_t value, Unit unit)
Create a Time equal to value in unit unit.
Definition: nstime.h:499
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:413
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
int simclick_sim_send(simclick_node_t *simnode, int ifid, int type, const unsigned char *data, int len, simclick_simpacketinfo *pinfo)
int simclick_sim_command(simclick_node_t *simnode, int cmd,...)
#define INTERFACE_ID_FIRST
#define INTERFACE_ID_FIRST_DROP
static int simstrlcpy(char *buf, int len, const std::string &s)
struct simclick_node simclick_node_t
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t data[writeSize]