23 #include "ns3/queue.h" 
   24 #include "ns3/simulator.h" 
   25 #include "ns3/ethernet-header.h" 
   26 #include "ns3/ethernet-trailer.h" 
   27 #include "ns3/llc-snap-header.h" 
   28 #include "ns3/boolean.h" 
   29 #include "ns3/uinteger.h" 
   30 #include "ns3/pointer.h" 
   31 #include "ns3/string.h" 
   32 #include "ns3/trace-source-accessor.h" 
   33 #include "ns3/channel.h" 
   34 #include "ns3/system-thread.h" 
   35 #include "ns3/mac48-address.h" 
   40 #include <sys/socket.h> 
   42 #include <sys/ioctl.h> 
   43 #include <net/ethernet.h> 
   45 #include <netinet/in.h> 
   46 #include <netpacket/packet.h> 
   47 #include <arpa/inet.h> 
   61 #define EMU_MAGIC 65867 
   68     .AddConstructor<EmuNetDevice> ()
 
   69     .AddAttribute (
"Mtu", 
"The MAC-level Maximum Transmission Unit",
 
   72                    MakeUintegerChecker<uint16_t> ())
 
   73     .AddAttribute (
"Address", 
 
   74                    "The ns-3 MAC address of this (virtual) device.",
 
   77                    MakeMac48AddressChecker ())
 
   78     .AddAttribute (
"DeviceName", 
 
   79                    "The name of the underlying real device (e.g. eth1).",
 
   83     .AddAttribute (
"Start", 
 
   84                    "The simulation time at which to spin up the device thread.",
 
   88     .AddAttribute (
"Stop", 
 
   89                    "The simulation time at which to tear down the device thread.",
 
   93     .AddAttribute (
"EncapsulationMode", 
 
   94                    "The link-layer encapsulation type to use.",
 
  106     .AddAttribute (
"TxQueue", 
 
  107                    "A queue to use as the transmit queue in the device.",
 
  110                    MakePointerChecker<Queue> ())
 
  112     .AddAttribute (
"RxQueueSize", 
"Maximum size of the read queue.  " 
  113                    "This value limits number of packets that have been read " 
  114                    "from the network into a memory buffer but have not yet " 
  115                    "been processed by the simulator.",
 
  118                    MakeUintegerChecker<uint32_t> ())
 
  128     .AddTraceSource (
"MacTx", 
 
  129                      "Trace source indicating a packet has arrived for transmission by this device",
 
  131     .AddTraceSource (
"MacTxDrop", 
 
  132                      "Trace source indicating a packet has been dropped by the device before transmission",
 
  134     .AddTraceSource (
"MacPromiscRx", 
 
  135                      "A packet has been received by this device, has been passed up from the physical layer " 
  136                      "and is being forwarded up the local protocol stack.  This is a promiscuous trace,",
 
  138     .AddTraceSource (
"MacRx", 
 
  139                      "A packet has been received by this device, has been passed up from the physical layer " 
  140                      "and is being forwarded up the local protocol stack.  This is a non-promiscuous trace,",
 
  144     .AddTraceSource (
"MacRxDrop", 
 
  145                      "Trace source indicating a packet was dropped before being forwarded up the stack",
 
  157     .AddTraceSource (
"PhyTxBegin", 
 
  158                      "Trace source indicating a packet has begun transmitting over the channel",
 
  160     .AddTraceSource (
"PhyTxEnd", 
 
  161                      "Trace source indicating a packet has been completely transmitted over the channel",
 
  163     .AddTraceSource (
"PhyTxDrop", 
 
  164                      "Trace source indicating a packet has been dropped by the device during transmission",
 
  166     .AddTraceSource (
"PhyRxBegin", 
 
  167                      "Trace source indicating a packet has begun being received by the device",
 
  169     .AddTraceSource (
"PhyRxEnd", 
 
  170                      "Trace source indicating a packet has been completely received by the device",
 
  172     .AddTraceSource (
"PhyRxDrop", 
 
  173                      "Trace source indicating a packet has been dropped by the device during reception",
 
  179     .AddTraceSource (
"Sniffer", 
 
  180                      "Trace source simulating a non-promiscuous packet sniffer attached to the device",
 
  182     .AddTraceSource (
"PromiscSniffer", 
 
  183                      "Trace source simulating a promiscuous packet sniffer attached to the device",
 
  195     m_ifIndex (std::numeric_limits<uint32_t>::max ()), 
 
  197     m_isBroadcast (true),
 
  198     m_isMulticast (false),
 
  199     m_pendingReadCount (0)
 
  272       NS_FATAL_ERROR (
"EmuNetDevice::StartDevice(): Device is already started");
 
  296   bzero (&ifr, 
sizeof(ifr));
 
  297   strncpy ((
char *)ifr.ifr_name, 
m_deviceName.c_str (), IFNAMSIZ);
 
  300   int32_t rc = ioctl (
m_sock, SIOCGIFINDEX, &ifr);
 
  303       NS_FATAL_ERROR (
"EmuNetDevice::StartDevice(): Can't get interface index");
 
  314   struct sockaddr_ll ll;
 
  315   bzero (&ll, 
sizeof(ll));
 
  317   ll.sll_family = AF_PACKET;
 
  319   ll.sll_protocol = htons (ETH_P_ALL);
 
  323   rc = bind (
m_sock, (
struct sockaddr *)&ll, 
sizeof (ll));
 
  326       NS_FATAL_ERROR (
"EmuNetDevice::StartDevice(): Can't bind to specified interface");
 
  329   rc = ioctl (
m_sock, SIOCGIFFLAGS, &ifr);
 
  332       NS_FATAL_ERROR (
"EmuNetDevice::StartDevice(): Can't get interface flags");
 
  346   if ((ifr.ifr_flags & IFF_PROMISC) == 0)
 
  350   if ((ifr.ifr_flags & IFF_BROADCAST) != IFF_BROADCAST)
 
  358   if ((ifr.ifr_flags & IFF_MULTICAST) == IFF_MULTICAST)
 
  369       NS_FATAL_ERROR (
"EmuNetDevice::StartDevice(): Receive thread is already running");
 
  393   int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
 
  396       NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): Unix socket creation error, errno = " << std::strerror (errno));
 
  402   struct sockaddr_un un;
 
  403   memset (&un, 0, 
sizeof (un));
 
  404   un.sun_family = AF_UNIX;
 
  405   int status = bind (sock, (
struct sockaddr*)&un, 
sizeof (sa_family_t));
 
  408       NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): Could not bind(): errno = " << std::strerror (errno));
 
  421   socklen_t len = 
sizeof (un);
 
  422   status = getsockname (sock, (
struct sockaddr*)&un, &len);
 
  425       NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): Could not getsockname(): errno = " << std::strerror (errno));
 
  432   NS_LOG_INFO (
"Encoded Unix socket as \"" << path << 
"\"");
 
  444   pid_t pid = ::fork ();
 
  454       std::ostringstream oss;
 
  456       NS_LOG_INFO (
"Parameters set to \"" << oss.str () << 
"\"");
 
  461       status = ::execlp (EMU_SOCK_CREATOR,
 
  470       NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): Back from execlp(), errno = " << std::strerror (errno));
 
  480       pid_t waited = waitpid (pid, &st, 0);
 
  483           NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): waitpid() fails, errno = " << std::strerror (errno));
 
  485       NS_ASSERT_MSG (pid == waited, 
"EmuNetDevice::CreateSocket(): pid mismatch");
 
  494           int exitStatus = WEXITSTATUS (st);
 
  497               NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): socket creator exited normally with status " << exitStatus);
 
  502           NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): socket creator exited abnormally");
 
  518       iov.iov_base = &magic;
 
  519       iov.iov_len = 
sizeof(magic);
 
  532       size_t msg_size = 
sizeof(int);
 
  533       char control[CMSG_SPACE (msg_size)];
 
  550       msg.msg_control = control;
 
  551       msg.msg_controllen = 
sizeof (control);
 
  558       ssize_t bytesRead = recvmsg (sock, &msg, 0);
 
  559       if (bytesRead != 
sizeof(
int))
 
  561           NS_FATAL_ERROR (
"EmuNetDevice::CreateSocket(): Wrong byte count from socket creator");
 
  569       struct cmsghdr *cmsg;
 
  570       for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR (&msg, cmsg))
 
  572           if (cmsg->cmsg_level == SOL_SOCKET &&
 
  573               cmsg->cmsg_type == SCM_RIGHTS)
 
  582                   NS_LOG_INFO (
"Got SCM_RIGHTS with correct magic " << magic);
 
  583                   int *rawSocket = (
int*)CMSG_DATA (cmsg);
 
  584                   NS_LOG_INFO (
"Got the socket from the socket creator = " << *rawSocket);
 
  590                   NS_LOG_INFO (
"Got SCM_RIGHTS, but with bad magic " << magic);
 
  594       NS_FATAL_ERROR (
"Did not get the raw socket from the socket creator");
 
  621   Ptr<Packet> packet = Create<Packet> (
reinterpret_cast<const uint8_t *
> (buf), len);
 
  754   struct sockaddr_ll addr;
 
  755   socklen_t addrSize = 
sizeof (addr);
 
  779           struct timespec time = { 0, 100000000L }; 
 
  780           nanosleep (&time, NULL);
 
  788       uint32_t bufferSize = 65536;
 
  789       uint8_t *buf = (uint8_t *)std::malloc (bufferSize);
 
  792           NS_FATAL_ERROR (
"EmuNetDevice::ReadThread(): malloc packet buffer failed");
 
  796       len = recvfrom (
m_sock, buf, bufferSize, 0, (
struct sockaddr *)&addr, &addrSize);
 
  806       NS_LOG_INFO (
"EmuNetDevice::ReadThread(): Scheduling handler");
 
  897   NS_ASSERT_MSG (packet, 
"EmuNetDevice::SendFrom(): packet zero from queue");
 
  902   struct sockaddr_ll ll;
 
  903   bzero (&ll, 
sizeof (ll));
 
  905   ll.sll_family = AF_PACKET;
 
  907   ll.sll_protocol = htons (ETH_P_ALL);
 
  917   return rc == -1 ? 
false : 
true;
 
  992   bzero (&ifr, 
sizeof (ifr));
 
  995   int32_t fd = socket (PF_INET, SOCK_DGRAM, IPPROTO_IP);
 
  998   int32_t rc = ioctl (fd, SIOCGIFMTU, &ifr);
 
 1001       NS_FATAL_ERROR (
"EmuNetDevice::GetMtu(): Can't ioctl SIOCGIFMTU");
 
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer. 
keep track of time values and allow control of global simulation resolution 
void StopDevice(void)
Tear down the device. 
virtual ~EmuNetDevice()
Destroy a EmuNetDevice. 
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
#define NS_LOG_FUNCTION(parameters)
Ptr< const AttributeChecker > MakeEnumChecker(int v1, std::string n1, int v2, std::string n2, int v3, std::string n3, int v4, std::string n4, int v5, std::string n5, int v6, std::string n6, int v7, std::string n7, int v8, std::string n8, int v9, std::string n9, int v10, std::string n10, int v11, std::string n11, int v12, std::string n12, int v13, std::string n13, int v14, std::string n14, int v15, std::string n15, int v16, std::string n16, int v17, std::string n17, int v18, std::string n18, int v19, std::string n19, int v20, std::string n20, int v21, std::string n21, int v22, std::string n22)
SystemMutex m_pendingReadMutex
virtual bool NeedsArp(void) const 
Ptr< Queue > m_queue
The Queue which this EmuNetDevice uses as a packet source. 
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device...
std::string EmuBufferToString(uint8_t *buffer, uint32_t len)
Convert a byte buffer to a string containing a hex representation of the buffer. 
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
hold variables of type string 
std::string m_deviceName
The unix/linux name of the underlying device (e.g., eth0) 
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
uint8_t * m_packetBuffer
A 64K buffer to hold packet data while it is being sent. 
virtual bool IsBroadcast(void) const 
EncapsulationMode
Enumeration of the types of packets supported in the class. 
uint64_t GetUid(void) const 
A packet is allocated a new uid when it is created empty or with zero-filled payload. 
bool IsNull(void) const 
Check for null implementation. 
virtual bool SupportsSendFrom(void) const 
bool m_isBroadcast
Flag indicating whether or not the underlying net device supports broadcast. 
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
Ptr< Queue > GetQueue(void) const 
Get a copy of the attached Queue. 
void StartDevice(void)
Spin up the device. 
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device. 
uint32_t GetSize(void) const 
bool IsBroadcast(void) const 
virtual void SetNode(Ptr< Node > node)
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the phy layer drops a packet as it tries to transmit it. 
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
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...
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function. 
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached. 
void ReadThread(void)
Loop to read and process packets. 
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
virtual void SetIfIndex(const uint32_t index)
NetDevice::PromiscReceiveCallback m_promiscRxCallback
The callback used to notify higher layers that a packet has been received in promiscuous mode...
TracedCallback< Ptr< const Packet > > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium. 
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
The trace source fired when packets coming into the "top" of the device at the L3/L2 transition are d...
Ptr< Node > m_node
The Node to which this device is attached. 
void Start(Time tStart)
Set a start time for the device. 
static TypeId GetTypeId(void)
#define NS_FATAL_ERROR(msg)
fatal error handling 
a polymophic address class 
virtual uint32_t GetIfIndex(void) const 
virtual Address GetAddress(void) const 
Class for representing data rates. 
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium. 
bool m_linkUp
Flag indicating whether or not the link is up. 
void SetQueue(Ptr< Queue > queue)
Attach a queue to the EmuNetDevice. 
hold variables of type 'enum' 
static Mac48Address GetMulticast(Ipv4Address address)
hold objects of type ns3::Time 
virtual uint16_t GetMtu(void) const 
A class which provides a simple way to implement a Critical Section. 
virtual Ptr< Node > GetNode(void) const 
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but which are dropped before b...
Hold an unsigned integer type. 
virtual Ptr< Channel > GetChannel(void) const 
Ptr< SystemThread > m_readThread
EmuNetDevice::EncapsulationMode GetEncapsulationMode(void) const 
Get the encapsulation mode of this device. 
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
EmuNetDevice()
Construct a EmuNetDevice. 
void SetEncapsulationMode(EmuNetDevice::EncapsulationMode mode)
Set the encapsulation mode of this device. 
void Stop(Time tStop)
Set a stop time for the device. 
static void ScheduleWithContext(uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event with the given context. 
NetDevice::ReceiveCallback m_rxCallback
The callback used to notify higher layers that a packet has been received. 
#define NS_LOG_LOGIC(msg)
static Mac48Address ConvertFrom(const Address &address)
virtual void SetPromiscReceiveCallback(PromiscReceiveCallback cb)
Ptr< Packet > Copy(void) const 
uint32_t m_ifIndex
The ns-3 interface index (in the sense of net device index) that has been assigned to this network de...
TracedCallback m_linkChangeCallbacks
Callbacks to fire if the link changes state (up or down). 
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium. ...
void ForwardUp(uint8_t *buf, uint32_t len)
Method to handle received packets. 
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
virtual bool IsPointToPoint(void) const 
Is this a point to point link? 
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
bool m_isMulticast
Flag indicating whether or not the underlying net device supports multicast. 
NS_LOG_COMPONENT_DEFINE("EmuNetDevice")
virtual void SetAddress(Address address)
Set the address of this interface. 
virtual bool IsLinkUp(void) const 
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
void SetDataRate(DataRate bps)
Set the Data Rate used for transmission of packets. 
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet begins the reception process from the medium. 
uint32_t m_pendingReadCount
#define NS_ASSERT_MSG(condition, message)
Describes an IPv6 address. 
Ipv4 addresses are stored in host order in this class. 
void ConnectWithoutContext(const CallbackBase &callback)
uint32_t GetId(void) const 
Time m_tStart
Time to start spinning up the device. 
int32_t m_sll_ifindex
The Unix interface index that we got from the system and which corresponds to the interface (e...
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition...
uint32_t m_maxPendingReads
Time m_tStop
Time to start tearing down the device. 
Network layer to device interface. 
hold objects of type ns3::Mac48Address 
#define NS_LOG_DEBUG(msg)
void CreateSocket(void)
Call out to a separate process running as suid root in order to get a raw socket. ...
virtual Address GetMulticast(Ipv4Address multicastGroup) const 
Make and return a MAC multicast address using the provided multicast group. 
EventImpl * MakeEvent(void(*f)(void))
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range. 
uint32_t CopyData(uint8_t *buffer, uint32_t size) const 
Copy the packet contents to a byte buffer. 
DIX II / Ethernet II packet. 
virtual void AddLinkChangeCallback(Callback< void > callback)
PacketType
Packet types are used as they are in Linux. 
EncapsulationMode m_encapMode
The type of packet that should be created by the AddHeader function and that should be processed by t...
virtual bool SetMtu(const uint16_t mtu)
a unique identifier for an interface. 
virtual Address GetBroadcast(void) const 
TypeId SetParent(TypeId tid)
virtual bool IsMulticast(void) const 
void AddHeader(const Header &header)
Add header to this packet. 
virtual bool IsBridge(void) const 
Is this a bridge? 
Mac48Address m_address
The MAC address which has been assigned to this device. 
TracedCallback< Ptr< const Packet > > m_phyRxDropTrace
The trace source fired when the phy layer drops a packet it has received.