Add TapNetDevice (formerly known as VirtualNetDevice)

This commit is contained in:
Gustavo J. A. M. Carneiro
2009-05-24 16:18:20 +01:00
parent d103e5418c
commit 7605d91dbe
5 changed files with 453 additions and 0 deletions

View File

@@ -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

View File

@@ -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

1
src/devices/tap-net-device/waf vendored Executable file
View File

@@ -0,0 +1 @@
exec "`dirname "$0"`"/../../../waf "$@"

View File

@@ -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',
]

View File

@@ -23,6 +23,7 @@ all_modules = (
'devices/emu',
'devices/bridge',
'devices/tap-bridge',
'devices/tap-net-device',
'applications/onoff',
'applications/packet-sink',
'applications/udp-echo',