# HG changeset patch # User Gustavo J. A. M. Carneiro # Date 1243178300 -3600 # Node ID dee7215f0334564512a8c6054eca8946cced626b # Parent 1b45505f9a5267879be430d9c7d07d9839c44576 Add TapNetDevice (formerly known as VirtualNetDevice) diff -r 1b45505f9a52 -r dee7215f0334 src/devices/tap-net-device/tap-net-device.cc --- /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 + */ + +#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 () + .AddConstructor () + .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, 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, 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 +TapNetDevice::GetChannel (void) const +{ + return Ptr (); +} + +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 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, const Address& dest, uint16_t protocolNumber) +{ + return SendFrom (packet, GetAddress (), dest, protocolNumber); +} + +bool +TapNetDevice::SendFrom (Ptr 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 +TapNetDevice::GetNode (void) const +{ + return m_node; +} + +void +TapNetDevice::SetNode (Ptr 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 diff -r 1b45505f9a52 -r dee7215f0334 src/devices/tap-net-device/tap-net-device.h --- /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 + */ + +#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, 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, 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, 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 GetChannel (void) const; + virtual Address GetAddress (void) const; + virtual uint16_t GetMtu (void) const; + virtual bool IsLinkUp (void) const; + virtual void SetLinkChangeCallback (Callback 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, const Address& dest, uint16_t protocolNumber); + virtual bool SendFrom (Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber); + virtual Ptr GetNode (void) const; + virtual void SetNode (Ptr 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 > m_rxTrace; + TracedCallback > m_txTrace; + Ptr 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 + diff -r 1b45505f9a52 -r dee7215f0334 src/devices/tap-net-device/waf --- /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 "$@" diff -r 1b45505f9a52 -r dee7215f0334 src/devices/tap-net-device/wscript --- /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', + ] + diff -r 1b45505f9a52 -r dee7215f0334 src/wscript --- 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',