|
A Discrete-Event Network Simulator
|
API
|
Go to the documentation of this file.
23 #include "ns3/channel.h"
24 #include "ns3/packet.h"
25 #include "ns3/ethernet-header.h"
26 #include "ns3/llc-snap-header.h"
28 #include "ns3/abort.h"
29 #include "ns3/boolean.h"
30 #include "ns3/string.h"
33 #include "ns3/simulator.h"
34 #include "ns3/realtime-simulator-impl.h"
35 #include "ns3/unix-fd-reader.h"
36 #include "ns3/uinteger.h"
40 #include <sys/socket.h>
42 #include <sys/ioctl.h>
57 uint32_t bufferSize = 65536;
58 uint8_t *buf = (uint8_t *)std::malloc (bufferSize);
62 ssize_t len = read (
m_fd, buf, bufferSize);
74 #define TAP_MAGIC 95549
83 .SetGroupName (
"TapBridge")
85 .AddAttribute (
"Mtu",
"The MAC-level Maximum Transmission Unit",
89 MakeUintegerChecker<uint16_t> ())
90 .AddAttribute (
"DeviceName",
91 "The name of the tap device to create.",
95 .AddAttribute (
"Gateway",
96 "The IP address of the default gateway to assign to the host machine, when in ConfigureLocal mode.",
100 .AddAttribute (
"IpAddress",
101 "The IP address to assign to the tap device, when in ConfigureLocal mode. "
102 "This address will override the discovered IP address of the simulated device.",
106 .AddAttribute (
"MacAddress",
107 "The MAC address to assign to the tap device, when in ConfigureLocal mode. "
108 "This address will override the discovered MAC address of the simulated device.",
112 .AddAttribute (
"Netmask",
113 "The network mask to assign to the tap device, when in ConfigureLocal mode. "
114 "This address will override the discovered MAC address of the simulated device.",
118 .AddAttribute (
"Start",
119 "The simulation time at which to spin up the tap device read thread.",
123 .AddAttribute (
"Stop",
124 "The simulation time at which to tear down the tap device read thread.",
128 .AddAttribute (
"Mode",
129 "The operating and configuration mode to use.",
135 .AddAttribute (
"Verbose",
136 "Enable verbose output from tap-creator child process",
151 m_ns3AddressRewritten (false)
315 int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
316 NS_ABORT_MSG_IF (sock == -1,
"TapBridge::CreateTap(): Unix socket creation error, errno = " << std::strerror (errno));
321 struct sockaddr_un un;
322 memset (&un, 0,
sizeof (un));
323 un.sun_family = AF_UNIX;
324 int status = bind (sock, (
struct sockaddr*)&un,
sizeof (sa_family_t));
325 NS_ABORT_MSG_IF (status == -1,
"TapBridge::CreateTap(): Could not bind(): errno = " << std::strerror (errno));
336 socklen_t len =
sizeof (un);
337 status = getsockname (sock, (
struct sockaddr*)&un, &len);
338 NS_ABORT_MSG_IF (status == -1,
"TapBridge::CreateTap(): Could not getsockname(): errno = " << std::strerror (errno));
344 NS_LOG_INFO (
"Encoded Unix socket as \"" << path <<
"\"");
362 pid_t pid = ::fork ();
401 NS_FATAL_ERROR (
"TapBridge::CreateTap(): Tap device IP configuration requested but neither IP address nor IP netmask is provided");
406 Ipv4Mask ipv4Mask (
"255.255.255.255");
410 uint32_t index = ipv4->GetInterfaceForDevice (nd);
411 if (ipv4->GetNAddresses (index) > 1)
413 NS_LOG_WARN (
"Underlying bridged NetDevice has multiple IP addresses; using first one.");
415 ipv4Address = ipv4->GetAddress (index, 0).GetLocal ();
420 ipv4Mask = ipv4->GetAddress (index, 0).GetMask ();
436 std::ostringstream ossDeviceName;
443 std::ostringstream ossGateway;
451 std::ostringstream ossIp;
454 ossIp <<
"-i" << ipv4Address;
461 std::ostringstream ossMac;
464 ossMac <<
"-m" << mac48Address;
471 std::ostringstream ossNetmask;
474 ossNetmask <<
"-n" << ipv4Mask;
481 std::ostringstream ossMode;
496 std::ostringstream ossVerbose;
502 std::ostringstream ossPath;
503 ossPath <<
"-p" << path;
506 " " << ossDeviceName.str () <<
507 " " << ossGateway.str () <<
508 " " << ossIp.str () <<
509 " " << ossMac.str () <<
510 " " << ossNetmask.str () <<
511 " " << ossMode.str () <<
512 " " << ossPath.str () <<
513 " " << ossVerbose.str ()
519 status = ::execlp (TAP_CREATOR,
521 ossDeviceName.str ().c_str (),
522 ossGateway.str ().c_str (),
523 ossIp.str ().c_str (),
524 ossMac.str ().c_str (),
525 ossNetmask.str ().c_str (),
526 ossMode.str ().c_str (),
527 ossPath.str ().c_str (),
528 ossVerbose.str ().c_str (),
535 NS_FATAL_ERROR (
"TapBridge::CreateTap(): Back from execlp(), status = " << status <<
536 " errno = " << ::strerror (errno));
546 pid_t waited = waitpid (pid, &st, 0);
547 NS_ABORT_MSG_IF (waited == -1,
"TapBridge::CreateTap(): waitpid() fails, errno = " << std::strerror (errno));
548 NS_ASSERT_MSG (pid == waited,
"TapBridge::CreateTap(): pid mismatch");
557 int exitStatus = WEXITSTATUS (st);
559 "TapBridge::CreateTap(): socket creator exited normally with status " << exitStatus);
561 else if (WIFSIGNALED (st))
563 NS_FATAL_ERROR (
"TapBridge::CreateTap(): socket creator exited with signal " << WTERMSIG (st));
567 NS_FATAL_ERROR (
"TapBridge::CreateTap(): socket creator exited abnormally");
585 iov.iov_base = &magic;
586 iov.iov_len =
sizeof(magic);
599 size_t msg_size =
sizeof(int);
600 char control[CMSG_SPACE (msg_size)];
617 msg.msg_control = control;
618 msg.msg_controllen =
sizeof (control);
625 ssize_t bytesRead = recvmsg (sock, &msg, 0);
626 NS_ABORT_MSG_IF (bytesRead !=
sizeof(
int),
"TapBridge::CreateTap(): Wrong byte count from socket creator");
633 struct cmsghdr *cmsg;
634 for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR (&msg, cmsg))
636 if (cmsg->cmsg_level == SOL_SOCKET &&
637 cmsg->cmsg_type == SCM_RIGHTS)
646 NS_LOG_INFO (
"Got SCM_RIGHTS with correct magic " << magic);
647 int *rawSocket = (
int*)CMSG_DATA (cmsg);
648 NS_LOG_INFO (
"Got the socket from the socket creator = " << *rawSocket);
654 NS_LOG_INFO (
"Got SCM_RIGHTS, but with bad magic " << magic);
660 NS_FATAL_ERROR (
"Did not get the raw socket from the socket creator");
670 memset (&s, 0,
sizeof(
struct ifreq));
674 int ioctlResult = ioctl (sock, SIOCGIFHWADDR, &s);
675 if (ioctlResult == 0)
678 learnedMac.
CopyFrom ((uint8_t *)s.ifr_hwaddr.sa_data);
679 NS_LOG_INFO (
"Learned Tap device MacAddr is " << learnedMac <<
": setting ns-3 device to use this address");
686 NS_LOG_INFO (
"Cannot get MacAddr of Tap device: " <<
m_tapDeviceName <<
" while in USE_LOCAL/USE_BRIDGE mode: " << std::strerror (errno));
687 NS_LOG_INFO (
"Underlying ns-3 device will continue to use default address, what can lead to connectivity errors");
716 NS_LOG_INFO (
"TapBridge::ReadCallback(): Scheduling handler");
752 Ptr<Packet> packet = Create<Packet> (
reinterpret_cast<const uint8_t *
> (buf), len);
770 NS_LOG_LOGIC (
"TapBridge::ForwardToBridgedDevice: Discarding packet as unfit for ns-3 consumption");
783 "TapBridge::ForwardToBridgedDevice: Source addr is broadcast");
791 NS_LOG_LOGIC (
"Learned MacAddr is " << learnedMac <<
": setting ns-3 device to use this address");
800 NS_LOG_LOGIC (
"Forwarding packet to ns-3 device via Send()");
921 NS_ASSERT_MSG (
m_node != 0,
"TapBridge::SetBridgedDevice: Bridge not installed in a node");
922 NS_ASSERT_MSG (bridgedDevice !=
this,
"TapBridge::SetBridgedDevice: Cannot bridge to self");
927 NS_FATAL_ERROR (
"TapBridge::SetBridgedDevice: Device does not support eui 48 addresses: cannot be added to bridge.");
932 NS_FATAL_ERROR (
"TapBridge::SetBridgedDevice: Device does not support SendFrom: cannot be added to bridge.");
953 NS_LOG_LOGIC (
"Discarding packet stolen from bridged device " << device);
966 NS_LOG_FUNCTION (
this << device << packet << protocol << src << dst << packetType);
1171 NS_FATAL_ERROR (
"TapBridge::Send: You may not call Send on a TapBridge directly");
1179 NS_FATAL_ERROR (
"TapBridge::Send: You may not call SendFrom on a TapBridge directly");
@ USE_LOCAL
ns-3 uses a pre-created tap, without configuring it
a unique identifier for an interface.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Ptr< NetDevice > GetBridgedNetDevice(void)
Get the bridged net device.
bool m_linkUp
Flag indicating whether or not the link is up.
EventImpl * MakeEvent(void(*f)(void))
Make an EventImpl from a function pointer taking varying numbers of arguments.
Ptr< Node > m_node
Pointer to the (ghost) Node to which we are connected.
Mac48Address m_tapMac
The MAC address to use as the hardware address on the host; only used in UseLocal mode.
void StartTapDevice(void)
Spin up the device.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
virtual Ptr< Channel > GetChannel(void) const
int m_fd
The file descriptor to read from.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
AttributeValue implementation for Boolean.
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
static Mac48Address GetMulticast(Ipv4Address address)
uint16_t m_mtu
The common mtu to use for the net devices.
static void ScheduleWithContext(uint32_t context, Time const &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Ptr< const AttributeAccessor > MakeIpv4AddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakeMac48AddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
virtual bool IsLinkUp(void) const
static bool IsMatchingType(const Address &address)
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
uint32_t GetId(void) const
void AddHeader(const Header &header)
Add header to this packet.
virtual Address GetAddress(void) const =0
NetDevice::ReceiveCallback m_rxCallback
Callback used to hook the standard packet receive callback of the TapBridge ns-3 net device.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void ForwardToBridgedDevice(uint8_t *buf, ssize_t len)
Forward a packet received from the tap device to the bridged ns-3 device.
std::string m_tapDeviceName
The name of the device to create on the host.
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
TapBridge::Mode GetMode(void)
Get the operating mode of this device.
virtual bool IsMulticast(void) const
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
uint32_t m_nodeId
a copy of the node id so the read thread doesn't have to GetNode() in in order to find the node ID.
FdReader::Data DoRead(void)
The read implementation.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
bool ReceiveFromBridgedDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, Address const &src, Address const &dst, PacketType packetType)
Receives a packet from a bridged Device.
Ipv4 addresses are stored in host order in this class.
void Stop(Time tStop)
Set a stop time for the device.
Describes an IPv6 address.
Mode
Enumeration of the operating modes supported in the class.
AttributeValue implementation for Ipv4Mask.
virtual void SetAddress(Address address)
Set the address of this interface.
Ptr< const AttributeChecker > MakeIpv4AddressChecker(void)
Mode m_mode
The operating mode of the bridge.
@ USE_BRIDGE
ns-3 uses a pre-created tap, and bridges to a bridging net device
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)=0
virtual void SetIfIndex(const uint32_t index)
EventId m_stopEvent
The ID of the ns-3 event used to schedule the tear down of the underlying host Tap device and ns-3 re...
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
AttributeValue implementation for Mac48Address.
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
virtual void DoDispose(void)
Call out to a separate process running as suid root in order to get our tap device created.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
virtual void SetReceiveCallback(ReceiveCallback cb)=0
Hold variables of type enum.
virtual uint16_t GetMtu(void) const
Mac48Address m_address
The (unused) MAC address of the TapBridge net device.
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
Ptr< TapBridgeFdReader > m_fdReader
Includes the ns-3 read thread used to do blocking reads on the fd corresponding to the host device.
Time m_tStop
Time to start tearing down the device.
virtual Address GetBroadcast(void) const
virtual void SetAddress(Address address)=0
Set the address of this interface.
uint8_t * m_packetBuffer
A 64K buffer to hold packet data while it is being sent.
Ptr< const AttributeChecker > MakeMac48AddressChecker(void)
Access to the IPv4 forwarding table, interfaces, and configuration.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
virtual bool IsBroadcast(void) const
virtual void AddLinkChangeCallback(Callback< void > callback)
Ptr< NetDevice > m_bridgedDevice
The ns-3 net device to which we are bridging.
@ PACKET_OTHERHOST
Packet addressed to someone else.
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Ipv4Address m_tapGateway
The IP address to use as the device default gateway on the host.
Ipv4Mask m_tapNetmask
The network mask to assign to the device created on the host.
void SetBridgedNetDevice(Ptr< NetDevice > bridgedDevice)
Set the ns-3 net device to bridge.
a polymophic address class
virtual void SetNode(Ptr< Node > node)
static Mac48Address ConvertFrom(const Address &address)
static TypeId GetTypeId(void)
Get the type ID.
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
void ReadCallback(uint8_t *buf, ssize_t len)
Callback to process packets that are read.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
void StopTapDevice(void)
Tear down the device.
bool IsBroadcast(void) const
virtual Ptr< Node > GetNode(void) const =0
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
TracedCallback m_linkChangeCallbacks
Callbacks to fire if the link changes state (up or down).
virtual bool IsBridge(void) const
Return true if the net device is acting as a bridge.
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Simulation virtual time values and global simulation resolution.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)=0
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
bool IsBroadcast(void) const
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
void CreateTap(void)
Call out to a separate process running as suid root in order to get our tap device created.
Ptr< const AttributeAccessor > MakeIpv4MaskAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
virtual uint32_t GetIfIndex(void) const
EventId m_startEvent
The ID of the ns-3 event used to schedule the start up of the underlying host Tap device and ns-3 rea...
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Hold variables of type string.
uint32_t m_ifIndex
The ns-3 interface index of this TapBridge net device.
bool m_verbose
Flag indicating whether or not the link is up.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
virtual void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Ipv4Address m_tapIp
The IP address to use as the device IP on the host.
virtual bool SetMtu(const uint16_t mtu)
virtual bool IsPointToPoint(void) const
Return true if the net device is on a point-to-point link.
void NotifyLinkUp(void)
Notifies that the link is up and ready.
Time Seconds(double value)
Construct a Time in the indicated unit.
virtual Ptr< Node > GetNode(void) const
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Time m_tStart
Time to start spinning up the device.
static Ipv4Mask GetOnes(void)
uint32_t pktSize
packet size used for the simulation (in bytes)
bool m_ns3AddressRewritten
Whether the MAC address of the underlying ns-3 device has already been rewritten is stored in this va...
AttributeValue implementation for Time.
virtual Address GetAddress(void) const
bool DiscardFromBridgedDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, Address const &src)
Receives a packet from a bridged Device.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
a class to represent an Ipv4 address mask
virtual bool SupportsSendFrom() const
virtual bool NeedsArp(void) const
Ptr< const AttributeChecker > MakeStringChecker(void)
NetDevice::PromiscReceiveCallback m_promiscRxCallback
Callback used to hook the promiscuous packet receive callback of the TapBridge ns-3 net device.
PacketType
Packet types are used as they are in Linux.
Hold an unsigned integer type.
@ CONFIGURE_LOCAL
ns-3 creates and configures tap device
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
void SetMode(TapBridge::Mode mode)
Set the operating mode of this device.
Ptr< Packet > Filter(Ptr< Packet > packet, Address *src, Address *dst, uint16_t *type)
The host we are bridged to is in the evil real world.
Ptr< const AttributeChecker > MakeIpv4MaskChecker(void)
void CopyFrom(const uint8_t buffer[6])
virtual bool SupportsSendFrom(void) const =0
std::string TapBufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer.
int m_sock
The socket (actually interpreted as fd) to use to talk to the Tap device on the real internet host.
A bridge to make it appear that a real host process is connected to an ns-3 net device.
virtual void DoDispose(void)
Destructor implementation.
void Start(Time tStart)
Set a start time for the device.
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)=0
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
uint64_t GetUid(void) const
Returns the packet's Uid.
Network layer to device interface.
A structure representing data read.
AttributeValue implementation for Ipv4Address.