in simulation/src/click/model/ipv4-click-routing.cc [628:836]
int simclick_sim_command (simclick_node_t *simnode, int cmd, ...)
{
va_list val;
va_start (val, cmd);
int retval = 0;
ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance = ns3::Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode);
switch (cmd)
{
case SIMCLICK_VERSION:
{
retval = 0;
break;
}
case SIMCLICK_SUPPORTS:
{
int othercmd = va_arg (val, int);
retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
break;
}
case SIMCLICK_IFID_FROM_NAME:
{
const char *ifname = va_arg (val, const char *);
retval = clickInstance->GetInterfaceId (ifname);
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IFID_FROM_NAME: " << ifname << " " << retval);
break;
}
case SIMCLICK_IPADDR_FROM_NAME:
{
const char *ifname = va_arg (val, const char *);
char *buf = va_arg (val, char *);
int len = va_arg (val, int);
int ifid = clickInstance->GetInterfaceId (ifname);
if (ifid >= 0)
{
retval = simstrlcpy (buf, len, clickInstance->GetIpAddressFromInterfaceId (ifid));
}
else
{
retval = -1;
}
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
break;
}
case SIMCLICK_IPPREFIX_FROM_NAME:
{
const char *ifname = va_arg (val, const char *);
char *buf = va_arg (val, char *);
int len = va_arg (val, int);
int ifid = clickInstance->GetInterfaceId (ifname);
if (ifid >= 0)
{
retval = simstrlcpy (buf, len, clickInstance->GetIpPrefixFromInterfaceId (ifid));
}
else
{
retval = -1;
}
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPPREFIX_FROM_NAME: " << ifname << " " << buf << " " << len);
break;
}
case SIMCLICK_MACADDR_FROM_NAME:
{
const char *ifname = va_arg (val, const char *);
char *buf = va_arg (val, char *);
int len = va_arg (val, int);
int ifid = clickInstance->GetInterfaceId (ifname);
if (ifid >= 0)
{
retval = simstrlcpy (buf, len, clickInstance->GetMacAddressFromInterfaceId (ifid));
}
else
{
retval = -1;
}
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_MACADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
break;
}
case SIMCLICK_SCHEDULE:
{
const struct timeval *when = va_arg (val, const struct timeval *);
clickInstance->HandleScheduleFromClick (when);
retval = 0;
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_SCHEDULE at " << when->tv_sec << "s and " << when->tv_usec << "usecs.");
break;
}
case SIMCLICK_GET_NODE_NAME:
{
char *buf = va_arg (val, char *);
int len = va_arg (val, int);
retval = simstrlcpy (buf, len, clickInstance->GetNodeName ());
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_GET_NODE_NAME: " << buf << " " << len);
break;
}
case SIMCLICK_IF_PROMISC:
{
int ifid = va_arg(val, int);
clickInstance->SetPromisc (ifid);
retval = 0;
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_PROMISC: " << ifid << " " << ns3::Simulator::Now ());
break;
}
case SIMCLICK_IF_READY:
{
int ifid = va_arg (val, int); // Commented out so that optimized build works
// We're not using a ClickQueue, so we're always ready (for the timebeing)
retval = clickInstance->IsInterfaceReady (ifid);
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_READY: " << ifid << " " << ns3::Simulator::Now ());
break;
}
case SIMCLICK_TRACE:
{
// Used only for tracing
NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_TRACE");
break;
}
case SIMCLICK_GET_NODE_ID:
{
// Used only for tracing
NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_GET_NODE_ID");
break;
}
case SIMCLICK_GET_RANDOM_INT:
{
uint32_t *randomValue = va_arg (val, uint32_t *);
uint32_t maxValue = va_arg (val, uint32_t);
*randomValue = static_cast<uint32_t> (clickInstance->GetRandomVariable ()->GetValue (0.0, static_cast<double> (maxValue) + 1.0));
retval = 0;
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_RANDOM: " << *randomValue << " " << maxValue << " " << ns3::Simulator::Now ());
break;
}
case SIMCLICK_GET_DEFINES:
{
char *buf = va_arg (val, char *);
size_t *size = va_arg (val, size_t *);
uint32_t required = 0;
// Try to fill the buffer with up to size bytes.
// If this is not enough space, write the required buffer size into
// the size variable and return an error code.
// Otherwise return the bytes actually writte into the buffer in size.
// Append key/value pair, separated by \0.
std::map<std::string, std::string> defines = clickInstance->GetDefines ();
std::map<std::string, std::string>::const_iterator it = defines.begin ();
while (it != defines.end ())
{
size_t available = *size - required;
if (it->first.length() + it->second.length() + 2 <= available)
{
simstrlcpy(buf + required, available, it->first);
required += it->first.length() + 1;
available -= it->first.length() + 1;
simstrlcpy(buf + required, available, it->second);
required += it->second.length() + 1;
}
else
{
required += it->first.length() + it->second.length() + 2;
}
it++;
}
if (required > *size)
{
retval = -1;
}
else
{
retval = 0;
}
*size = required;
}
}
va_end (val);
return retval;
}