24 #include "ns3/ipv4-interface.h"
26 #include "ns3/mac48-address.h"
28 #include "ns3/random-variable-stream.h"
29 #include "ns3/simulator.h"
31 #include <click/simclick.h>
43 #define INTERFACE_ID_KERNELTAP 0
44 #define INTERFACE_ID_FIRST 1
45 #define INTERFACE_ID_FIRST_DROP 33
56 .AddConstructor<Ipv4ClickRouting>()
57 .SetGroupName(
"Click");
63 : m_nonDefaultName(false),
66 m_random = CreateObject<UniformRandomVariable>();
80 uint32_t
id =
m_ipv4->GetObject<
Node>()->GetId();
84 std::stringstream name;
144 std::map<std::string, std::string>
186 if (strstr(ifname,
"tap") || strstr(ifname,
"tun"))
190 else if (
const char* devname = strstr(ifname,
"eth"))
192 while (*devname && !isdigit((
unsigned char)*devname))
202 else if (
const char* devname = strstr(ifname,
"drop"))
204 while (*devname && !isdigit((
unsigned char)*devname))
218 if (retval >= (
int)
m_ipv4->GetNInterfaces())
229 return ifid >= 0 && ifid < static_cast<int>(
m_ipv4->GetNInterfaces());
235 std::stringstream addr;
236 m_ipv4->GetAddress(ifid, 0).GetLocal().Print(addr);
244 std::stringstream addr;
245 m_ipv4->GetAddress(ifid, 0).GetMask().Print(addr);
253 std::stringstream addr;
256 Address devAddr = device->GetAddress();
277 struct timeval curtime;
278 uint64_t remainder = 0;
303 if (curtime.tv_usec == 1000000)
326 NS_LOG_DEBUG(
"HandleScheduleFromClick at " << when->tv_sec <<
" " << when->tv_usec <<
" "
346 NS_LOG_DEBUG(
"Incoming packet from tap0. Sending Packet up the stack.");
354 ipv4l3->LocalDeliver(p, ipHeader, (uint32_t)ifid);
358 NS_LOG_DEBUG(
"Incoming packet from eth" << ifid - 1 <<
" of type " << ptype
359 <<
". Sending packet down the stack.");
363 DynamicCast<Ipv4L3ClickProtocol>(
m_ipv4)->SendDown(p, ifid);
375 simclick_simpacketinfo pinfo;
379 simclick_click_send(
m_simNode, ifid, ptype,
data, len, &pinfo);
388 for (ifid = 0; ifid <
m_ipv4->GetNInterfaces(); ifid++)
399 auto buf =
new uint8_t[len];
416 for (ifid = 0; ifid <
m_ipv4->GetNInterfaces(); ifid++)
427 auto buf =
new uint8_t[len];
439 char* handle = simclick_click_read_handler(
m_simNode,
444 std::string ret(handle);
456 std::string handlerName,
457 std::string writeString)
459 int r = simclick_click_write_handler(
m_simNode,
462 writeString.c_str());
478 ipv4l3->SetPromisc(ifid);
489 std::stringstream addr;
494 NS_LOG_DEBUG(
"Probe click routing table for " << addr.str());
498 size_t pos = s.find(
' ');
501 if (pos == std::string::npos)
505 interfaceId = atoi(s.c_str());
506 NS_LOG_DEBUG(
"case 1: destination " << destination <<
" interfaceId " << interfaceId);
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);
515 if (interfaceId != -1)
517 rtentry = Create<Ipv4Route>();
523 uint32_t numOifAddresses =
m_ipv4->GetNAddresses(interfaceId);
526 if (numOifAddresses == 1)
528 ifAddr =
m_ipv4->GetAddress(interfaceId, 0);
535 rtentry->SetSource(ifAddr.
GetLocal());
536 rtentry->SetGateway(destination);
537 rtentry->SetOutputDevice(
m_ipv4->GetNetDevice(interfaceId));
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());
565 NS_FATAL_ERROR(
"Click router does not have a RouteInput() interface!");
572 *stream->
GetStream() <<
"\nCLICK Routing table printing is not yet implemented, skipping.\n";
606 if ((
unsigned)len > s.length())
623 const unsigned char*
data,
625 simclick_simpacketinfo* pinfo)
628 << ifid <<
" " <<
type <<
" " <<
data <<
" "
657 case SIMCLICK_VERSION: {
662 case SIMCLICK_SUPPORTS: {
663 int othercmd = va_arg(val,
int);
664 retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
668 case SIMCLICK_IFID_FROM_NAME: {
669 const char* ifname = va_arg(val,
const char*);
674 <<
" SIMCLICK_IFID_FROM_NAME: " << ifname <<
" " << retval);
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);
695 <<
" SIMCLICK_IPADDR_FROM_NAME: " << ifname <<
" " << buf <<
" " << len);
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);
716 <<
" SIMCLICK_IPPREFIX_FROM_NAME: " << ifname <<
" " << buf <<
" " << len);
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);
736 <<
" SIMCLICK_MACADDR_FROM_NAME: " << ifname <<
" " << buf <<
" " << len);
740 case SIMCLICK_SCHEDULE: {
741 const struct timeval* when = va_arg(val,
const struct timeval*);
747 <<
"s and " << when->tv_usec <<
"usecs.");
752 case SIMCLICK_GET_NODE_NAME: {
753 char* buf = va_arg(val,
char*);
754 int len = va_arg(val,
int);
758 <<
" SIMCLICK_GET_NODE_NAME: " << buf <<
" " << len);
762 case SIMCLICK_IF_PROMISC: {
763 int ifid = va_arg(val,
int);
772 case SIMCLICK_IF_READY: {
773 int ifid = va_arg(val,
int);
783 case SIMCLICK_TRACE: {
789 case SIMCLICK_GET_NODE_ID: {
795 case SIMCLICK_GET_RANDOM_INT: {
796 uint32_t* randomValue = va_arg(val, uint32_t*);
797 uint32_t maxValue = va_arg(val, uint32_t);
799 *randomValue =
static_cast<uint32_t
>(
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;
818 std::map<std::string, std::string> defines = clickInstance->
GetDefines();
820 for (
auto it = defines.begin(); it != defines.end(); it++)
822 size_t available = *size - required;
823 if (it->first.length() + it->second.length() + 2 <= available)
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;
833 required += it->first.length() + it->second.length() + 2;
836 if (required > *size)
a polymophic address class
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.
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.
~Ipv4ClickRouting() override
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.
a class to store IPv4 address information on an interface
Ipv4Address GetLocal() const
Get the local address.
Abstract base class for IPv4 routing protocols.
static Mac48Address ConvertFrom(const Address &address)
virtual void DoDispose()
Destructor implementation.
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
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.
static Time Now()
Return the current simulation virtual time.
SocketErrno
Enumeration of the possible errors returned by a socket.
Simulation virtual time values and global simulation resolution.
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
int64_t GetFemtoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
static Unit GetResolution()
Unit
The unit to use to interpret a number representing time.
int64_t GetPicoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
static Time FromInteger(uint64_t value, Unit unit)
Create a Time equal to value in unit unit.
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#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.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#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.
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.