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