13#include "ns3/ipv4-interface.h" 
   15#include "ns3/mac48-address.h" 
   17#include "ns3/random-variable-stream.h" 
   18#include "ns3/simulator.h" 
   20#include <click/simclick.h> 
   32#define INTERFACE_ID_KERNELTAP 0 
   33#define INTERFACE_ID_FIRST 1 
   34#define INTERFACE_ID_FIRST_DROP 33 
   45                            .AddConstructor<Ipv4ClickRouting>()
 
   46                            .SetGroupName(
"Click");
 
 
   52    : m_nonDefaultName(false),
 
 
   73        std::stringstream name;
 
 
  133std::map<std::string, std::string>
 
  175    if (strstr(ifname, 
"tap") || strstr(ifname, 
"tun"))
 
  179    else if (
const char* devname = strstr(ifname, 
"eth"))
 
  181        while (*devname && !isdigit((
unsigned char)*devname))
 
  191    else if (
const char* devname = strstr(ifname, 
"drop"))
 
  193        while (*devname && !isdigit((
unsigned char)*devname))
 
 
  224    std::stringstream addr;
 
 
  233    std::stringstream addr;
 
 
  242    std::stringstream addr;
 
  245    Address devAddr = device->GetAddress();
 
 
  266    struct timeval curtime;
 
  267    uint64_t remainder = 0;
 
  269    Time now = Simulator::Now();
 
  274    switch (Time::GetResolution())
 
  292        if (curtime.tv_usec == 1000000)
 
 
  315    NS_LOG_DEBUG(
"HandleScheduleFromClick at " << when->tv_sec << 
" " << when->tv_usec << 
" " 
 
  335        NS_LOG_DEBUG(
"Incoming packet from tap0. Sending Packet up the stack.");
 
  341        p->RemoveHeader(ipHeader);
 
  343        ipv4l3->LocalDeliver(p, ipHeader, (
uint32_t)ifid);
 
  347        NS_LOG_DEBUG(
"Incoming packet from eth" << ifid - 1 << 
" of type " << ptype
 
  348                                                << 
". Sending packet down the stack.");
 
 
  364    simclick_simpacketinfo pinfo;
 
  368    simclick_click_send(
m_simNode, ifid, ptype, 
data, len, &pinfo);
 
 
  387    int len = p->GetSize();
 
  388    auto buf = 
new uint8_t[len];
 
  389    p->CopyData(buf, len);
 
 
  415    int len = p->GetSize();
 
  416    auto buf = 
new uint8_t[len];
 
  417    p->CopyData(buf, len);
 
 
  428    char* handle = simclick_click_read_handler(
m_simNode,
 
  433    std::string ret(handle);
 
 
  445                               std::string handlerName,
 
  446                               std::string writeString)
 
  448    int r = simclick_click_write_handler(
m_simNode,
 
  451                                         writeString.c_str());
 
 
  467    ipv4l3->SetPromisc(ifid);
 
 
  478    std::stringstream addr;
 
  483    NS_LOG_DEBUG(
"Probe click routing table for " << addr.str());
 
  487    size_t pos = s.find(
' ');
 
  490    if (pos == std::string::npos)
 
  494        interfaceId = atoi(s.c_str());
 
  495        NS_LOG_DEBUG(
"case 1:  destination " << destination << 
" interfaceId " << interfaceId);
 
  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);
 
  504    if (interfaceId != -1)
 
  515        if (numOifAddresses == 1)
 
  524        rtentry->SetSource(ifAddr.
GetLocal());
 
  525        rtentry->SetGateway(destination);
 
  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());
 
 
  554    NS_FATAL_ERROR(
"Click router does not have a RouteInput() interface!");
 
 
  561    *stream->GetStream() << 
"\nCLICK Routing table printing is not yet implemented, skipping.\n";
 
 
  595        if ((
unsigned)len > s.length())
 
 
  612                  const unsigned char* 
data,
 
  614                  simclick_simpacketinfo* pinfo)
 
  617                                                << ifid << 
" " << type << 
" " << 
data << 
" " 
  628    clickInstance->HandlePacketFromClick(ifid, type, 
data, len);
 
 
  646    case SIMCLICK_VERSION: {
 
  651    case SIMCLICK_SUPPORTS: {
 
  652        int othercmd = va_arg(val, 
int);
 
  653        retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
 
  657    case SIMCLICK_IFID_FROM_NAME: {
 
  658        const char* ifname = va_arg(val, 
const char*);
 
  660        retval = clickInstance->GetInterfaceId(ifname);
 
  663                     << 
" SIMCLICK_IFID_FROM_NAME: " << ifname << 
" " << retval);
 
  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);
 
  672        int ifid = clickInstance->GetInterfaceId(ifname);
 
  676            retval = 
simstrlcpy(buf, len, clickInstance->GetIpAddressFromInterfaceId(ifid));
 
  684                     << 
" SIMCLICK_IPADDR_FROM_NAME: " << ifname << 
" " << buf << 
" " << len);
 
  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);
 
  693        int ifid = clickInstance->GetInterfaceId(ifname);
 
  697            retval = 
simstrlcpy(buf, len, clickInstance->GetIpPrefixFromInterfaceId(ifid));
 
  705                     << 
" SIMCLICK_IPPREFIX_FROM_NAME: " << ifname << 
" " << buf << 
" " << len);
 
  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);
 
  717            retval = 
simstrlcpy(buf, len, clickInstance->GetMacAddressFromInterfaceId(ifid));
 
  725                     << 
" SIMCLICK_MACADDR_FROM_NAME: " << ifname << 
" " << buf << 
" " << len);
 
  729    case SIMCLICK_SCHEDULE: {
 
  730        const struct timeval* when = va_arg(val, 
const struct timeval*);
 
  732        clickInstance->HandleScheduleFromClick(when);
 
  735        NS_LOG_DEBUG(clickInstance->GetNodeName() << 
" SIMCLICK_SCHEDULE at " << when->tv_sec
 
  736                                                  << 
"s and " << when->tv_usec << 
"usecs.");
 
  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());
 
  747                     << 
" SIMCLICK_GET_NODE_NAME: " << buf << 
" " << len);
 
  751    case SIMCLICK_IF_PROMISC: {
 
  752        int ifid = va_arg(val, 
int);
 
  753        clickInstance->SetPromisc(ifid);
 
  761    case SIMCLICK_IF_READY: {
 
  762        int ifid = va_arg(val, 
int); 
 
  765        retval = clickInstance->IsInterfaceReady(ifid);
 
  772    case SIMCLICK_TRACE: {
 
  774        NS_LOG_DEBUG(clickInstance->GetNodeName() << 
" Received a call for SIMCLICK_TRACE");
 
  778    case SIMCLICK_GET_NODE_ID: {
 
  780        NS_LOG_DEBUG(clickInstance->GetNodeName() << 
" Received a call for SIMCLICK_GET_NODE_ID");
 
  784    case SIMCLICK_GET_RANDOM_INT: {
 
  788        *randomValue = 
static_cast<uint32_t>(
 
  789            clickInstance->GetRandomVariable()->GetValue(0.0, 
static_cast<double>(maxValue) + 1.0));
 
  791        NS_LOG_DEBUG(clickInstance->GetNodeName() << 
" SIMCLICK_RANDOM: " << *randomValue << 
" " 
  796    case SIMCLICK_GET_DEFINES: {
 
  797        char* buf = va_arg(val, 
char*);
 
  798        size_t* size = va_arg(val, 
size_t*);
 
  807        std::map<std::string, std::string> defines = clickInstance->GetDefines();
 
  809        for (
auto it = defines.begin(); it != defines.end(); it++)
 
  811            size_t available = *size - required;
 
  812            if (it->first.length() + it->second.length() + 2 <= available)
 
  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;
 
  822                required += it->first.length() + it->second.length() + 2;
 
  825        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.
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.
static Mac48Address ConvertFrom(const Address &address)
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
virtual void DoDispose()
Destructor implementation.
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.
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 ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
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.