--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/tap-net-device/tap-net-device.cc Sun May 24 16:18:20 2009 +0100
@@ -0,0 +1,271 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,2009 INESC Porto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
+ */
+
+#include "ns3/log.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/mac48-address.h"
+#include "ns3/llc-snap-header.h"
+#include "ns3/error-model.h"
+#include "tap-net-device.h"
+#include "ns3/channel.h"
+#include "ns3/trace-source-accessor.h"
+
+
+NS_LOG_COMPONENT_DEFINE ("TapNetDevice");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (TapNetDevice);
+
+TypeId
+TapNetDevice::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::TapNetDevice")
+ .SetParent<NetDevice> ()
+ .AddConstructor<TapNetDevice> ()
+ .AddTraceSource ("Rx", "Received payload from the MAC layer.",
+ MakeTraceSourceAccessor (&TapNetDevice::m_rxTrace))
+ .AddTraceSource ("Tx", "Send payload to the MAC layer.",
+ MakeTraceSourceAccessor (&TapNetDevice::m_txTrace))
+ ;
+ return tid;
+}
+
+TapNetDevice::TapNetDevice ()
+{
+ m_needsArp = false;
+ m_supportsSendFrom = true;
+ m_mtu = 65535;
+}
+
+
+void
+TapNetDevice::SetSendFromCallback (SendFromCallback sendCb)
+{
+ m_sendCb = sendCb;
+}
+
+void
+TapNetDevice::SetNeedsArp (bool needsArp)
+{
+ m_needsArp = needsArp;
+}
+
+void
+TapNetDevice::SetSupportsSendFrom (bool supportsSendFrom)
+{
+ m_supportsSendFrom = supportsSendFrom;
+}
+
+bool
+TapNetDevice::SetMtu (const uint16_t mtu)
+{
+ m_mtu = mtu;
+ return true;
+}
+
+
+TapNetDevice::~TapNetDevice()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+}
+
+
+void TapNetDevice::DoDispose()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+ NetDevice::DoDispose ();
+}
+
+bool
+TapNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol, const Address &address)
+{
+ if (m_rxCallback (this, packet, protocol, address))
+ {
+ m_rxTrace (packet);
+ return true;
+ }
+ return false;
+}
+
+bool
+TapNetDevice::PromiscReceive (Ptr<Packet> packet, uint16_t protocol,
+ const Address &source, const Address &destination,
+ PacketType packetType)
+{
+ if (m_promiscRxCallback (this, packet, protocol, source, destination, packetType))
+ {
+ m_rxTrace (packet);
+ return true;
+ }
+ return false;
+}
+
+
+void
+TapNetDevice::SetName (const std::string name)
+{
+ m_name = name;
+}
+
+std::string
+TapNetDevice::GetName (void) const
+{
+ return m_name;
+}
+
+void
+TapNetDevice::SetIfIndex (const uint32_t index)
+{
+ m_index = index;
+}
+
+uint32_t
+TapNetDevice::GetIfIndex (void) const
+{
+ return m_index;
+}
+
+Ptr<Channel>
+TapNetDevice::GetChannel (void) const
+{
+ return Ptr<Channel> ();
+}
+
+Address
+TapNetDevice::GetAddress (void) const
+{
+ return Mac48Address ();
+}
+
+uint16_t
+TapNetDevice::GetMtu (void) const
+{
+ return m_mtu;
+}
+
+bool
+TapNetDevice::IsLinkUp (void) const
+{
+ return true;
+}
+
+void
+TapNetDevice::SetLinkChangeCallback (Callback<void> callback)
+{
+}
+
+bool
+TapNetDevice::IsBroadcast (void) const
+{
+ return m_needsArp;
+}
+
+Address
+TapNetDevice::GetBroadcast (void) const
+{
+ return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+bool
+TapNetDevice::IsMulticast (void) const
+{
+ return false;
+}
+
+Address TapNetDevice::GetMulticast (Ipv4Address multicastGroup) const
+{
+ return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+Address TapNetDevice::GetMulticast (Ipv6Address addr) const
+{
+ return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+
+bool
+TapNetDevice::IsPointToPoint (void) const
+{
+ return true;
+}
+
+bool
+TapNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+{
+ return SendFrom (packet, GetAddress (), dest, protocolNumber);
+}
+
+bool
+TapNetDevice::SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
+{
+ NS_FATAL_ERROR ("not implemented");
+ if (m_sendCb (packet, source, dest, protocolNumber))
+ {
+ m_txTrace (packet);
+ return true;
+ }
+ return false;
+}
+
+Ptr<Node>
+TapNetDevice::GetNode (void) const
+{
+ return m_node;
+}
+
+void
+TapNetDevice::SetNode (Ptr<Node> node)
+{
+ m_node = node;
+}
+
+bool
+TapNetDevice::NeedsArp (void) const
+{
+ return m_needsArp;
+}
+
+void
+TapNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
+{
+ m_rxCallback = cb;
+}
+
+void
+TapNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+ m_promiscRxCallback = cb;
+}
+
+bool
+TapNetDevice::SupportsSendFrom () const
+{
+ return m_supportsSendFrom;
+}
+
+bool TapNetDevice::IsBridge (void) const
+{
+ return false;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/tap-net-device/tap-net-device.h Sun May 24 16:18:20 2009 +0100
@@ -0,0 +1,166 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008,2009 INESC Porto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
+ */
+
+#ifndef TAP_NET_DEVICE_H
+#define TAP_NET_DEVICE_H
+
+#include "ns3/address.h"
+#include "ns3/node.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/ptr.h"
+#include "ns3/traced-callback.h"
+
+namespace ns3 {
+
+
+/**
+ * \class TapNetDevice
+ * \brief A virtual device, similar to Linux TAP interfaces.
+ *
+ * A TapNetDevice is a "virtual" NetDevice implementation which
+ * delegates to a user callback (see method SetSendFromCallback()) the
+ * task of actually transmitting a packet. It also allows the user
+ * code to inject the packet as if it had been received by the
+ * TapNetDevice. Together, these features allow one to build tunnels.
+ * For instance, by transmitting packets into a UDP socket we end up
+ * building an IP-over-UDP-over-IP tunnel.
+ *
+ * The same thing could be accomplished by subclassing NetDevice
+ * directly. However, TapNetDevice is usually much simpler to program
+ * than a NetDevice subclass.
+ */
+class TapNetDevice : public NetDevice
+{
+public:
+ typedef Callback<bool, Ptr<Packet>, const Address&, const Address&, uint16_t> SendFromCallback;
+
+ static TypeId GetTypeId (void);
+ TapNetDevice ();
+
+ virtual ~TapNetDevice ();
+
+ /**
+ * \brief Set the user callback to be called when a L2 packet is to be transmitted
+ * \param transmitCb the new transmit callback
+ */
+ void SetSendFromCallback (SendFromCallback transmitCb);
+
+ /**
+ * \brief Configure whether the virtual device needs ARP
+ *
+ * \param needsArp the the 'needs arp' value that will be returned
+ * by the NeedsArp() method. The method IsBroadcast() will also
+ * return this value.
+ */
+ void SetNeedsArp (bool needsArp);
+
+ /**
+ * \brief Configure whether the virtual device supports SendFrom
+ */
+ void SetSupportsSendFrom (bool supportsSendFrom);
+
+ /**
+ * \brief Configure the reported MTU for the virtual device. The
+ * default value is 65535.
+ * \return whether the MTU value was within legal bounds
+ */
+ bool SetMtu (const uint16_t mtu);
+
+
+ /**
+ * \param p packet sent from below up to Network Device
+ * \param protocol Protocol type
+ * \param source the address of the sender of this packet.
+ * \returns true if the packet was forwarded successfully,
+ * false otherwise.
+ *
+ * Forward a "virtually received" packet up the node's protocol
+ * stack.
+ */
+ bool Receive (Ptr<Packet> packet, uint16_t protocol, const Address &source);
+
+
+ /**
+ * \param p packet sent from below up to Network Device
+ * \param protocol Protocol type
+ * \param source the address of the sender of this packet.
+ * \param destination the address of the receiver of this packet.
+ * \param packetType type of packet received (broadcast/multicast/unicast/otherhost)
+ * \returns true if the packet was forwarded successfully, false otherwise.
+ *
+ * Forward a "virtually received (in promiscuous mode)" packet up
+ * the node's protocol stack.
+ */
+ bool PromiscReceive (Ptr<Packet> packet, uint16_t protocol,
+ const Address &source, const Address &destination,
+ PacketType packetType);
+
+
+ // inherited from NetDevice base class.
+ virtual void SetName(const std::string name);
+ virtual std::string GetName(void) const;
+ virtual void SetIfIndex(const uint32_t index);
+ virtual uint32_t GetIfIndex(void) const;
+ virtual Ptr<Channel> GetChannel (void) const;
+ virtual Address GetAddress (void) const;
+ virtual uint16_t GetMtu (void) const;
+ virtual bool IsLinkUp (void) const;
+ virtual void SetLinkChangeCallback (Callback<void> callback);
+ virtual bool IsBroadcast (void) const;
+ virtual Address GetBroadcast (void) const;
+ virtual bool IsMulticast (void) const;
+ virtual Address GetMulticast (Ipv4Address multicastGroup) const;
+ virtual Address GetMulticast (Ipv6Address addr) const;
+ virtual bool IsPointToPoint (void) const;
+ virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
+ virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
+ virtual Ptr<Node> GetNode (void) const;
+ virtual void SetNode (Ptr<Node> node);
+ virtual bool NeedsArp (void) const;
+ virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+ virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
+ virtual bool SupportsSendFrom () const;
+ virtual bool IsBridge (void) const;
+
+protected:
+
+ virtual void DoDispose (void);
+
+private:
+
+ SendFromCallback m_sendCb;
+ TracedCallback<Ptr<const Packet> > m_rxTrace;
+ TracedCallback<Ptr<const Packet> > m_txTrace;
+ Ptr<Node> m_node;
+ ReceiveCallback m_rxCallback;
+ PromiscReceiveCallback m_promiscRxCallback;
+ std::string m_name;
+ uint32_t m_index;
+ uint16_t m_mtu;
+ bool m_needsArp;
+ bool m_supportsSendFrom;
+};
+
+}; // namespace ns3
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/tap-net-device/waf Sun May 24 16:18:20 2009 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/tap-net-device/wscript Sun May 24 16:18:20 2009 +0100
@@ -0,0 +1,14 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+ module = bld.create_ns3_module('tap-net-device', ['node'])
+ module.source = [
+ 'tap-net-device.cc',
+ ]
+ headers = bld.new_task_gen('ns3header')
+ headers.module = 'tap-net-device'
+ headers.source = [
+ 'tap-net-device.h',
+ ]
+
--- a/src/wscript Sun May 24 11:39:41 2009 +0100
+++ b/src/wscript Sun May 24 16:18:20 2009 +0100
@@ -23,6 +23,7 @@
'devices/emu',
'devices/bridge',
'devices/tap-bridge',
+ 'devices/tap-net-device',
'applications/onoff',
'applications/packet-sink',
'applications/udp-echo',