00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "emu-net-device.h"
00020 #include "emu-encode-decode.h"
00021
00022 #include "ns3/log.h"
00023 #include "ns3/queue.h"
00024 #include "ns3/simulator.h"
00025 #include "ns3/realtime-simulator-impl.h"
00026 #include "ns3/mac48-address.h"
00027 #include "ns3/ethernet-header.h"
00028 #include "ns3/ethernet-trailer.h"
00029 #include "ns3/llc-snap-header.h"
00030 #include "ns3/trace-source-accessor.h"
00031 #include "ns3/pointer.h"
00032 #include "ns3/channel.h"
00033 #include "ns3/system-thread.h"
00034 #include "ns3/string.h"
00035 #include "ns3/boolean.h"
00036
00037 #include <sys/wait.h>
00038 #include <sys/stat.h>
00039 #include <sys/socket.h>
00040 #include <sys/un.h>
00041 #include <sys/ioctl.h>
00042 #include <net/ethernet.h>
00043 #include <net/if.h>
00044 #include <netinet/in.h>
00045 #include <netpacket/packet.h>
00046 #include <arpa/inet.h>
00047 #include <errno.h>
00048 #include <limits>
00049 #include <stdlib.h>
00050
00051 NS_LOG_COMPONENT_DEFINE ("EmuNetDevice");
00052
00053 namespace ns3 {
00054
00055 NS_OBJECT_ENSURE_REGISTERED (EmuNetDevice);
00056
00057 #define EMU_MAGIC 65867
00058
00059 TypeId
00060 EmuNetDevice::GetTypeId (void)
00061 {
00062 static TypeId tid = TypeId ("ns3::EmuNetDevice")
00063 .SetParent<NetDevice> ()
00064 .AddConstructor<EmuNetDevice> ()
00065 .AddAttribute ("Address",
00066 "The ns-3 MAC address of this (virtual) device.",
00067 Mac48AddressValue (Mac48Address ("ff:ff:ff:ff:ff:ff")),
00068 MakeMac48AddressAccessor (&EmuNetDevice::m_address),
00069 MakeMac48AddressChecker ())
00070 .AddAttribute ("DeviceName",
00071 "The name of the underlying real device (e.g. eth1).",
00072 StringValue ("eth1"),
00073 MakeStringAccessor (&EmuNetDevice::m_deviceName),
00074 MakeStringChecker ())
00075 .AddAttribute ("Start",
00076 "The simulation time at which to spin up the device thread.",
00077 TimeValue (Seconds (0.)),
00078 MakeTimeAccessor (&EmuNetDevice::m_tStart),
00079 MakeTimeChecker ())
00080 .AddAttribute ("Stop",
00081 "The simulation time at which to tear down the device thread.",
00082 TimeValue (Seconds (0.)),
00083 MakeTimeAccessor (&EmuNetDevice::m_tStop),
00084 MakeTimeChecker ())
00085 .AddAttribute ("TxQueue",
00086 "A queue to use as the transmit queue in the device.",
00087 PointerValue (),
00088 MakePointerAccessor (&EmuNetDevice::m_queue),
00089 MakePointerChecker<Queue> ())
00090 .AddTraceSource ("Rx",
00091 "Trace source indicating recvfrom of packet destined for broadcast, multicast or local address.",
00092 MakeTraceSourceAccessor (&EmuNetDevice::m_rxTrace))
00093 ;
00094 return tid;
00095 }
00096
00097
00098 EmuNetDevice::EmuNetDevice ()
00099 :
00100 m_startEvent (),
00101 m_stopEvent (),
00102 m_sock (-1),
00103 m_readThread (0),
00104 m_ifIndex (std::numeric_limits<uint32_t>::max ()),
00105 m_sll_ifindex (-1),
00106 m_name ("Emu NetDevice")
00107 {
00108 NS_LOG_FUNCTION (this);
00109 Start (m_tStart);
00110 }
00111
00112 EmuNetDevice::~EmuNetDevice ()
00113 {
00114 }
00115
00116 void
00117 EmuNetDevice::DoDispose()
00118 {
00119 NS_LOG_FUNCTION_NOARGS ();
00120 m_node = 0;
00121 NetDevice::DoDispose ();
00122 }
00123
00124 void
00125 EmuNetDevice::Start (Time tStart)
00126 {
00127 NS_LOG_FUNCTION (tStart);
00128
00129
00130
00131
00132 Simulator::Cancel (m_startEvent);
00133 m_startEvent = Simulator::Schedule (tStart, &EmuNetDevice::StartDevice, this);
00134 }
00135
00136 void
00137 EmuNetDevice::Stop (Time tStop)
00138 {
00139 NS_LOG_FUNCTION (tStop);
00140
00141
00142
00143 Simulator::Cancel (m_stopEvent);
00144 m_startEvent = Simulator::Schedule (tStop, &EmuNetDevice::StopDevice, this);
00145 }
00146
00147 void
00148 EmuNetDevice::StartDevice (void)
00149 {
00150 NS_LOG_FUNCTION_NOARGS ();
00151
00152
00153
00154
00155 if (m_sock != -1)
00156 {
00157 NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): Device is already started");
00158 }
00159
00160 NS_LOG_LOGIC ("Creating socket");
00161
00162
00163
00164
00165
00166 CreateSocket ();
00167
00168
00169
00170
00171 struct ifreq ifr;
00172 bzero (&ifr, sizeof(ifr));
00173 strncpy ((char *)ifr.ifr_name, m_deviceName.c_str (), IFNAMSIZ);
00174
00175 NS_LOG_LOGIC ("Getting interface index");
00176 int32_t rc = ioctl (m_sock, SIOCGIFINDEX, &ifr);
00177 if (rc == -1)
00178 {
00179 NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): Can't get interface index");
00180 }
00181
00182
00183
00184
00185 m_sll_ifindex = ifr.ifr_ifindex;
00186
00187
00188
00189
00190 struct sockaddr_ll ll;
00191 bzero (&ll, sizeof(ll));
00192
00193 ll.sll_family = AF_PACKET;
00194 ll.sll_ifindex = m_sll_ifindex;
00195 ll.sll_protocol = htons(ETH_P_ALL);
00196
00197 NS_LOG_LOGIC ("Binding socket to interface");
00198
00199 rc = bind (m_sock, (struct sockaddr *)&ll, sizeof (ll));
00200 if (rc == -1)
00201 {
00202 NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): Can't bind to specified interface");
00203 }
00204
00205 rc = ioctl(m_sock, SIOCGIFFLAGS, &ifr);
00206 if (rc == -1)
00207 {
00208 NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): Can't get interface flags");
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 if ((ifr.ifr_flags & IFF_PROMISC) == 0)
00223 {
00224 NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): " << m_deviceName << " is not in promiscuous mode");
00225 }
00226
00227
00228
00229
00230 if (m_readThread != 0)
00231 {
00232 NS_FATAL_ERROR ("EmuNetDevice::StartDevice(): Receive thread is already running");
00233 }
00234
00235 NS_LOG_LOGIC ("Spinning up read thread");
00236
00237 m_readThread = Create<SystemThread> (MakeCallback (&EmuNetDevice::ReadThread, this));
00238 m_readThread->Start ();
00239
00240 NotifyLinkUp ();
00241 }
00242
00243 void
00244 EmuNetDevice::CreateSocket (void)
00245 {
00246 NS_LOG_FUNCTION_NOARGS ();
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 int sock = socket (PF_UNIX, SOCK_DGRAM, 0);
00257 if (sock == -1)
00258 {
00259 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Unix socket creation error, errno = " << strerror (errno));
00260 }
00261
00262
00263
00264
00265 struct sockaddr_un un;
00266 memset (&un, 0, sizeof (un));
00267 un.sun_family = AF_UNIX;
00268 int status = bind (sock, (struct sockaddr*)&un, sizeof (sa_family_t));
00269 if (status == -1)
00270 {
00271 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Could not bind(): errno = " << strerror (errno));
00272 }
00273
00274 NS_LOG_INFO ("Created Unix socket");
00275 NS_LOG_INFO ("sun_family = " << un.sun_family);
00276 NS_LOG_INFO ("sun_path = " << un.sun_path);
00277
00278
00279
00280
00281
00282
00283
00284 socklen_t len = sizeof (un);
00285 status = getsockname (sock, (struct sockaddr*)&un, &len);
00286 if (status == -1)
00287 {
00288 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Could not getsockname(): errno = " << strerror (errno));
00289 }
00290
00291
00292
00293
00294 std::string path = EmuBufferToString((uint8_t *)&un, len);
00295 NS_LOG_INFO ("Encoded Unix socket as \"" << path << "\"");
00296
00297
00298
00299
00300
00301 pid_t pid = ::fork ();
00302 if (pid == 0)
00303 {
00304 NS_LOG_DEBUG ("Child process");
00305
00306
00307
00308
00309
00310
00311 std::ostringstream oss;
00312 oss << "-p" << path;
00313 NS_LOG_INFO ("Parameters set to \"" << oss.str () << "\"");
00314
00315
00316
00317
00318 status = ::execl (FindCreator ().c_str (), "emu-sock-creator", oss.str ().c_str (), (char *)NULL);
00319
00320
00321
00322
00323
00324 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Back from execl(), errno = " << ::strerror (errno));
00325 }
00326 else
00327 {
00328 NS_LOG_DEBUG ("Parent process");
00329
00330
00331
00332
00333 int st;
00334 pid_t waited = waitpid (pid, &st, 0);
00335 if (waited == -1)
00336 {
00337 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): waitpid() fails, errno = " << strerror (errno));
00338 }
00339 NS_ASSERT_MSG (pid == waited, "EmuNetDevice::CreateSocket(): pid mismatch");
00340
00341
00342
00343
00344
00345
00346 if (WIFEXITED (st))
00347 {
00348 int exitStatus = WEXITSTATUS (st);
00349 if (exitStatus != 0)
00350 {
00351 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): socket creator exited normally with status " << exitStatus);
00352 }
00353 }
00354 else
00355 {
00356 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): socket creator exited abnormally");
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 struct iovec iov;
00371 uint32_t magic;
00372 iov.iov_base = &magic;
00373 iov.iov_len = sizeof(magic);
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 size_t msg_size = sizeof(int);
00387 char control[CMSG_SPACE(msg_size)];
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 struct msghdr msg;
00400 msg.msg_name = 0;
00401 msg.msg_namelen = 0;
00402 msg.msg_iov = &iov;
00403 msg.msg_iovlen = 1;
00404 msg.msg_control = control;
00405 msg.msg_controllen = sizeof (control);
00406 msg.msg_flags = 0;
00407
00408
00409
00410
00411
00412 ssize_t bytesRead = recvmsg (sock, &msg, 0);
00413 if (bytesRead != sizeof(int))
00414 {
00415 NS_FATAL_ERROR ("EmuNetDevice::CreateSocket(): Wrong byte count from socket creator");
00416 }
00417
00418
00419
00420
00421
00422
00423 struct cmsghdr *cmsg;
00424 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
00425 {
00426 if (cmsg->cmsg_level == SOL_SOCKET &&
00427 cmsg->cmsg_type == SCM_RIGHTS)
00428 {
00429
00430
00431
00432
00433
00434 if (magic == EMU_MAGIC)
00435 {
00436 NS_LOG_INFO ("Got SCM_RIGHTS with correct magic " << magic);
00437 int *rawSocket = (int*)CMSG_DATA (cmsg);
00438 NS_LOG_INFO ("Got the socket from the socket creator = " << *rawSocket);
00439 m_sock = *rawSocket;
00440 return;
00441 }
00442 else
00443 {
00444 NS_LOG_INFO ("Got SCM_RIGHTS, but with bad magic " << magic);
00445 }
00446 }
00447 }
00448 NS_FATAL_ERROR ("Did not get the raw socket from the socket creator");
00449 }
00450 }
00451
00452 std::string
00453 EmuNetDevice::FindCreator (void)
00454 {
00455 struct stat st;
00456 std::string debug = "./build/debug/src/devices/emu/emu-sock-creator";
00457 std::string optimized = "./build/optimized/src/devices/emu/emu-sock-creator";
00458
00459 if (::stat (debug.c_str (), &st) == 0)
00460 {
00461 return debug;
00462 }
00463
00464 if (::stat (optimized.c_str (), &st) == 0)
00465 {
00466 return optimized;
00467 }
00468
00469 NS_FATAL_ERROR ("EmuNetDevice::FindCreator(): Couldn't find creator");
00470 return "";
00471 }
00472
00473 void
00474 EmuNetDevice::StopDevice (void)
00475 {
00476 NS_LOG_FUNCTION_NOARGS ();
00477
00478 close (m_sock);
00479 m_sock = -1;
00480
00481 NS_ASSERT_MSG (m_readThread != 0, "EmuNetDevice::StopDevice(): Receive thread is not running");
00482
00483 NS_LOG_LOGIC ("Joining read thread");
00484 m_readThread->Join ();
00485 m_readThread = 0;
00486 }
00487
00488 void
00489 EmuNetDevice::ForwardUp (uint8_t *buf, uint32_t len)
00490 {
00491 NS_LOG_FUNCTION (buf << len);
00492
00493
00494
00495
00496 Ptr<Packet> packet = Create<Packet> (reinterpret_cast<const uint8_t *> (buf), len);
00497 free (buf);
00498 buf = 0;
00499
00500
00501
00502
00503
00504 Ptr<Packet> originalPacket = packet->Copy ();
00505
00506
00507
00508
00509 EthernetTrailer trailer;
00510 packet->RemoveTrailer (trailer);
00511 trailer.CheckFcs (packet);
00512
00513 EthernetHeader header (false);
00514 packet->RemoveHeader (header);
00515
00516 NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
00517 NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
00518
00519 LlcSnapHeader llc;
00520 packet->RemoveHeader (llc);
00521 uint16_t protocol = llc.GetType ();
00522
00523 PacketType packetType;
00524
00525 if (header.GetDestination ().IsBroadcast ())
00526 {
00527 NS_LOG_LOGIC ("Pkt destination is PACKET_BROADCAST");
00528 packetType = NS3_PACKET_BROADCAST;
00529 }
00530 else if (header.GetDestination ().IsMulticast ())
00531 {
00532 NS_LOG_LOGIC ("Pkt destination is PACKET_MULTICAST");
00533 packetType = NS3_PACKET_MULTICAST;
00534 }
00535 else if (header.GetDestination () == m_address)
00536 {
00537 NS_LOG_LOGIC ("Pkt destination is PACKET_HOST");
00538 packetType = NS3_PACKET_HOST;
00539 }
00540 else
00541 {
00542 NS_LOG_LOGIC ("Pkt destination is PACKET_OTHERHOST");
00543 packetType = NS3_PACKET_OTHERHOST;
00544 }
00545
00546 if (!m_promiscRxCallback.IsNull ())
00547 {
00548 NS_LOG_LOGIC ("calling m_promiscRxCallback");
00549 m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), packetType);
00550 }
00551
00552 if (packetType != NS3_PACKET_OTHERHOST)
00553 {
00554 m_rxTrace (originalPacket);
00555 NS_LOG_LOGIC ("calling m_rxCallback");
00556 m_rxCallback (this, packet, protocol, header.GetSource ());
00557 }
00558 }
00559
00560 void
00561 EmuNetDevice::ReadThread (void)
00562 {
00563 NS_LOG_FUNCTION_NOARGS ();
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 int32_t len = -1;
00575 struct sockaddr_ll addr;
00576 socklen_t addrSize = sizeof (addr);
00577
00578 for (;;)
00579 {
00580 uint32_t bufferSize = 65536;
00581 uint8_t *buf = (uint8_t *)malloc (bufferSize);
00582 if (buf == 0)
00583 {
00584 NS_FATAL_ERROR ("EmuNetDevice::ReadThread(): malloc packet buffer failed");
00585 }
00586
00587 NS_LOG_LOGIC ("Calling recvfrom");
00588 len = recvfrom (m_sock, buf, bufferSize, 0, (struct sockaddr *)&addr, &addrSize);
00589
00590 if (len == -1)
00591 {
00592 free (buf);
00593 buf = 0;
00594 return;
00595 }
00596
00597 NS_LOG_INFO ("EmuNetDevice::ReadThread(): Received packet");
00598 NS_LOG_INFO ("EmuNetDevice::ReadThread(): Scheduling handler");
00599 DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->ScheduleRealtimeNow (
00600 MakeEvent (&EmuNetDevice::ForwardUp, this, buf, len));
00601 buf = 0;
00602 }
00603 }
00604
00605 bool
00606 EmuNetDevice::Send (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
00607 {
00608 NS_LOG_FUNCTION (packet << dest << protocolNumber);
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 return SendFrom (packet, m_address, dest, protocolNumber);
00629 }
00630
00631 bool
00632 EmuNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &dest, uint16_t protocolNumber)
00633 {
00634 NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
00635
00636 if (IsLinkUp () == false)
00637 {
00638 NS_LOG_LOGIC ("Link is down, returning");
00639 return false;
00640 }
00641
00642 Mac48Address destination = Mac48Address::ConvertFrom (dest);
00643 Mac48Address source = Mac48Address::ConvertFrom (src);
00644
00645 NS_LOG_LOGIC ("Transmit packet with UID " << packet->GetUid ());
00646 NS_LOG_LOGIC ("Transmit packet from " << source);
00647 NS_LOG_LOGIC ("Transmit packet to " << destination);
00648
00649 #if 0
00650 {
00651 struct ifreq ifr;
00652 bzero (&ifr, sizeof(ifr));
00653 strncpy ((char *)ifr.ifr_name, m_deviceName.c_str (), IFNAMSIZ);
00654
00655 NS_LOG_LOGIC ("Getting MAC address");
00656 int32_t rc = ioctl (m_sock, SIOCGIFHWADDR, &ifr);
00657 if (rc == -1)
00658 {
00659 NS_FATAL_ERROR ("EmuNetDevice::SendFrom(): Can't get MAC address");
00660 }
00661
00662 std::ostringstream oss;
00663 oss << std::hex <<
00664 (ifr.ifr_hwaddr.sa_data[0] & 0xff) << ":" <<
00665 (ifr.ifr_hwaddr.sa_data[1] & 0xff) << ":" <<
00666 (ifr.ifr_hwaddr.sa_data[2] & 0xff) << ":" <<
00667 (ifr.ifr_hwaddr.sa_data[3] & 0xff) << ":" <<
00668 (ifr.ifr_hwaddr.sa_data[4] & 0xff) << ":" <<
00669 (ifr.ifr_hwaddr.sa_data[5] & 0xff) << std::dec;
00670
00671 NS_LOG_LOGIC ("Fixup source to HW MAC " << oss.str ());
00672 source = Mac48Address (oss.str ().c_str ());
00673 NS_LOG_LOGIC ("source now " << source);
00674 }
00675 #endif
00676
00677 LlcSnapHeader llc;
00678 llc.SetType (protocolNumber);
00679 packet->AddHeader (llc);
00680
00681 EthernetHeader header (false);
00682 header.SetSource (source);
00683 header.SetDestination (destination);
00684 header.SetLengthType (packet->GetSize ());
00685 packet->AddHeader (header);
00686
00687 EthernetTrailer trailer;
00688 trailer.CalcFcs (packet);
00689 packet->AddTrailer (trailer);
00690
00691
00692
00693
00694 m_queue->Enqueue (packet);
00695 packet = m_queue->Dequeue ();
00696
00697 struct sockaddr_ll ll;
00698 bzero (&ll, sizeof (ll));
00699
00700 ll.sll_family = AF_PACKET;
00701 ll.sll_ifindex = m_sll_ifindex;
00702 ll.sll_protocol = htons(ETH_P_ALL);
00703
00704 NS_LOG_LOGIC ("calling sendto");
00705
00706 int32_t rc;
00707 rc = sendto (m_sock, packet->PeekData (), packet->GetSize (), 0, reinterpret_cast<struct sockaddr *> (&ll), sizeof (ll));
00708
00709 NS_LOG_LOGIC ("sendto returns " << rc);
00710
00711 return rc == -1 ? false : true;
00712 }
00713
00714 void
00715 EmuNetDevice::SetDataRate(DataRate bps)
00716 {
00717 NS_LOG_FUNCTION (this << bps);
00718 NS_FATAL_ERROR ("EmuNetDevice::SetDataRate(): Unable.");
00719 }
00720
00721 void
00722 EmuNetDevice::SetQueue (Ptr<Queue> q)
00723 {
00724 NS_LOG_FUNCTION (this << q);
00725 m_queue = q;
00726 }
00727
00728 Ptr<Queue>
00729 EmuNetDevice::GetQueue(void) const
00730 {
00731 NS_LOG_FUNCTION_NOARGS ();
00732 return m_queue;
00733 }
00734
00735 void
00736 EmuNetDevice::NotifyLinkUp (void)
00737 {
00738 m_linkUp = true;
00739 if (!m_linkChangeCallback.IsNull ())
00740 {
00741 m_linkChangeCallback ();
00742 }
00743 }
00744
00745 void
00746 EmuNetDevice::SetName(const std::string name)
00747 {
00748 m_name = name;
00749 }
00750
00751 std::string
00752 EmuNetDevice::GetName(void) const
00753 {
00754 return m_name;
00755 }
00756
00757 void
00758 EmuNetDevice::SetIfIndex(const uint32_t index)
00759 {
00760 m_ifIndex = index;
00761 }
00762
00763 uint32_t
00764 EmuNetDevice::GetIfIndex(void) const
00765 {
00766 return m_ifIndex;
00767 }
00768
00769 Ptr<Channel>
00770 EmuNetDevice::GetChannel (void) const
00771 {
00772 NS_FATAL_ERROR ("EmuNetDevice::GetChannel(): Unable.");
00773 return 0;
00774 }
00775
00776 void
00777 EmuNetDevice::SetAddress (Mac48Address addr)
00778 {
00779 NS_LOG_FUNCTION (addr);
00780 m_address = addr;
00781 }
00782
00783 Address
00784 EmuNetDevice::GetAddress (void) const
00785 {
00786 NS_LOG_FUNCTION_NOARGS ();
00787 return m_address;
00788 }
00789
00790 bool
00791 EmuNetDevice::SetMtu (const uint16_t mtu)
00792 {
00793 NS_FATAL_ERROR ("EmuNetDevice::SetMtu(): Unable.");
00794 return false;
00795 }
00796
00797 uint16_t
00798 EmuNetDevice::GetMtu (void) const
00799 {
00800 struct ifreq ifr;
00801 bzero (&ifr, sizeof (ifr));
00802 strcpy(ifr.ifr_name, m_deviceName.c_str ());
00803
00804 int32_t fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
00805
00806
00807 int32_t rc = ioctl(fd, SIOCGIFMTU, &ifr);
00808 if (rc == -1)
00809 {
00810 NS_FATAL_ERROR ("EmuNetDevice::GetMtu(): Can't ioctl SIOCGIFMTU");
00811 }
00812
00813 close (fd);
00814
00815 return ifr.ifr_mtu;
00816 }
00817
00818 bool
00819 EmuNetDevice::IsLinkUp (void) const
00820 {
00821 return m_linkUp;
00822 }
00823
00824 void
00825 EmuNetDevice::SetLinkChangeCallback (Callback<void> callback)
00826 {
00827 m_linkChangeCallback = callback;
00828 }
00829
00830 bool
00831 EmuNetDevice::IsBroadcast (void) const
00832 {
00833 return true;
00834 }
00835
00836 Address
00837 EmuNetDevice::GetBroadcast (void) const
00838 {
00839 return Mac48Address ("ff:ff:ff:ff:ff:ff");
00840 }
00841
00842 bool
00843 EmuNetDevice::IsMulticast (void) const
00844 {
00845 return false;
00846 }
00847
00848 Address
00849 EmuNetDevice::GetMulticast (Ipv4Address multicastGroup) const
00850 {
00851 NS_LOG_FUNCTION (multicastGroup);
00852
00853 Mac48Address ad = Mac48Address::GetMulticast (multicastGroup);
00854
00855
00856
00857
00858
00859
00860 NS_LOG_LOGIC ("multicast address is " << ad);
00861
00862 return ad;
00863 }
00864
00865 Address
00866 EmuNetDevice::GetMulticast (Ipv6Address addr) const
00867 {
00868 NS_LOG_FUNCTION(this << addr);
00869
00870 Mac48Address ad = Mac48Address::GetMulticast (addr);
00871 NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
00872
00873 return ad;
00874 }
00875
00876 bool
00877 EmuNetDevice::IsPointToPoint (void) const
00878 {
00879 return false;
00880 }
00881
00882 bool
00883 EmuNetDevice::IsBridge (void) const
00884 {
00885 return false;
00886 }
00887
00888 void
00889 EmuNetDevice::SetPromiscReceiveCallback (PromiscReceiveCallback cb)
00890 {
00891 NS_FATAL_ERROR ("EmuNetDevice::SetPromiscReceiveCallback(): Not implemented");
00892 }
00893
00894 bool
00895 EmuNetDevice::SupportsSendFrom () const
00896 {
00897 NS_LOG_FUNCTION_NOARGS ();
00898 return true;
00899 }
00900
00901
00902 Ptr<Node>
00903 EmuNetDevice::GetNode (void) const
00904 {
00905 return m_node;
00906 }
00907
00908 void
00909 EmuNetDevice::SetNode (Ptr<Node> node)
00910 {
00911 m_node = node;
00912 }
00913
00914 bool
00915 EmuNetDevice::NeedsArp (void) const
00916 {
00917 return true;
00918 }
00919
00920 void
00921 EmuNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
00922 {
00923 m_rxCallback = cb;
00924 }
00925
00926 }