This commit is contained in:
Tom Henderson
2007-07-27 10:49:29 -07:00
35 changed files with 3115 additions and 67 deletions

168
examples/simple-csma-cd.cc Normal file
View File

@@ -0,0 +1,168 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* 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
*/
// Port of ns-2/tcl/ex/simple.tcl to ns-3
//
// Network topology
//
// n0
// |
// |
// n2---+----n3
// |
// |
// n1
//
// - CBR/UDP flows from n0 to n1, and from n3 to n0
// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
// (i.e., DataRate of 448,000 bps)
// - DropTail queues
// - Tracing of queues and packet receptions to file "simple-csma-cd.tr"
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/command-line.h"
#include "ns3/default-value.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
#include "ns3/debug.h"
#include "ns3/simulator.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/ascii-trace.h"
#include "ns3/pcap-trace.h"
#include "ns3/internet-node.h"
#include "ns3/csma-cd-channel.h"
#include "ns3/csma-cd-net-device.h"
#include "ns3/csma-cd-topology.h"
#include "ns3/csma-cd-ipv4-topology.h"
#include "ns3/mac-address.h"
#include "ns3/ipv4-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/onoff-application.h"
#include "ns3/ascii-trace.h"
#include "ns3/trace-context.h"
#include "ns3/trace-root.h"
using namespace ns3;
int main (int argc, char *argv[])
{
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
#if 0
DebugComponentEnable("Channel");
DebugComponentEnable("CsmaCdChannel");
DebugComponentEnable("CsmaCdNetDevice");
DebugComponentEnable("NetDevice");
DebugComponentEnable("PacketSocket");
#endif
// Set up some default values for the simulation. Use the Bind()
// technique to tell the system what subclass of Queue to use,
// and what the queue limit is
// The below Bind command tells the queue factory which class to
// instantiate, when the queue factory is invoked in the topology code
Bind ("Queue", "DropTailQueue");
// Allow the user to override any of the defaults and the above
// Bind()s at run-time, via command-line arguments
CommandLine::Parse (argc, argv);
// Here, we will explicitly create four nodes. In more sophisticated
// topologies, we could configure a node factory.
Ptr<Node> n0 = Create<InternetNode> ();
Ptr<Node> n1 = Create<InternetNode> ();
Ptr<Node> n2 = Create<InternetNode> ();
Ptr<Node> n3 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
Ptr<CsmaCdChannel> channel0 =
CsmaCdTopology::CreateCsmaCdChannel(
DataRate(5000000), MilliSeconds(2));
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0,
MacAddress("10:54:23:54:23:50"));
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
MacAddress("10:54:23:54:23:51"));
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
MacAddress("10:54:23:54:23:52"));
CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
MacAddress("10:54:23:54:23:53"));
// Later, we add IP addresses.
CsmaCdIpv4Topology::AddIpv4Address (
n0, 1, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
CsmaCdIpv4Topology::AddIpv4Address (
n1, 1, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
CsmaCdIpv4Topology::AddIpv4Address (
n2, 1, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
CsmaCdIpv4Topology::AddIpv4Address (
n3, 1, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
// Create the OnOff application to send UDP datagrams of size
// 210 bytes at a rate of 448 Kb/s
// from n0 to n1
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
n0,
Ipv4Address("10.1.1.2"),
80,
"Udp",
ConstantVariable(1),
ConstantVariable(0));
// Start the application
ooff->Start(Seconds(1.0));
ooff->Stop (Seconds(10.0));
// Create a similar flow from n3 to n0, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
Ipv4Address("10.1.1.1"),
80,
"Udp",
ConstantVariable(1),
ConstantVariable(0));
// Start the application
ooff->Start(Seconds(1.1));
ooff->Stop (Seconds(10.0));
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
// Trace output will be sent to the simple-p2p.tr file
AsciiTrace asciitrace ("simple-csma-cd.tr");
asciitrace.TraceAllNetDeviceRx ();
// asciitrace.TraceAllQueues ();
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -54,14 +54,14 @@
#include "ns3/ascii-trace.h"
#include "ns3/pcap-trace.h"
#include "ns3/internet-node.h"
#include "ns3/p2p-channel.h"
#include "ns3/p2p-net-device.h"
#include "ns3/point-to-point-channel.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/mac-address.h"
#include "ns3/ipv4-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
#include "ns3/p2p-topology.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
using namespace ns3;

View File

@@ -9,5 +9,6 @@ def build(bld):
obj.source = source
return obj
obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node'])
obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['point-to-point', 'internet-node'])
obj = create_ns_prog('simple-csma-cd', 'simple-csma-cd.cc', deps=['csma-cd', 'internet-node'])

View File

@@ -18,9 +18,9 @@ def build(bld):
obj = create_ns_prog('main-test', 'main-test.cc')
obj = create_ns_prog('main-simple', 'main-simple.cc',
deps=['node', 'internet-node', 'applications'])
#obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'p2p'])
#obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'point-to-point'])
obj = create_ns_prog('main-default-value', 'main-default-value.cc',
deps=['core', 'simulator', 'node', 'p2p'])
deps=['core', 'simulator', 'node', 'point-to-point'])
obj = create_ns_prog('main-grid-topology', 'main-grid-topology.cc',
deps=['core', 'simulator', 'mobility', 'internet-node'])
obj = create_ns_prog('main-random-topology', 'main-random-topology.cc',

View File

@@ -0,0 +1,83 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007, Emmanuelle Laprise
* All rights reserved.
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include "backoff.h"
namespace ns3 {
Backoff::Backoff()
{
m_slotTime = MicroSeconds(1);
m_minSlots = 1;
m_maxSlots = 1000;
m_ceiling = 10;
m_maxRetries = 1000;
ResetBackoffTime();
}
Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
uint32_t ceiling, uint32_t maxRetries)
{
m_slotTime = slotTime;
m_minSlots = minSlots;
m_maxSlots = maxSlots;
m_ceiling = ceiling;
m_maxRetries = maxRetries;
}
Time
Backoff::GetBackoffTime (void)
{
Time backoff;
uint32_t ceiling;
if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling))
ceiling = m_ceiling;
else
ceiling = m_numBackoffRetries;
uint32_t minSlot = m_minSlots;
uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1;
if (maxSlot > m_maxSlots)
maxSlot = m_maxSlots;
uint32_t backoffSlots =
(uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot);
backoff = Scalar(backoffSlots) * m_slotTime;
return (backoff);
}
void Backoff::ResetBackoffTime (void)
{
m_numBackoffRetries = 0;
}
bool Backoff::MaxRetriesReached(void) {
return (m_numBackoffRetries >= m_maxRetries);
}
void Backoff::IncrNumRetries(void) {
m_numBackoffRetries++;
}
} // namespace ns3

View File

@@ -0,0 +1,87 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
* Derived from the p2p net device file
Transmi */
#ifndef BACKOFF_H
#define BACKOFF_H
#include <stdint.h>
#include "ns3/nstime.h"
#include "ns3/random-variable.h"
namespace ns3 {
/**
* \brief The backoff class is used for calculating backoff times
* when many net devices can write to the same channel
*
*/
class Backoff {
public:
uint32_t m_minSlots; // Minimum number of backoff slots (when
// multiplied by m_slotTime, determines minimum
// backoff time)
uint32_t m_maxSlots; // Maximim number of backoff slots (when
// multiplied by m_slotTime, determines
// maximum backoff time)
uint32_t m_ceiling; // Caps the exponential function when the
// number of retries reaches m_ceiling
uint32_t m_maxRetries; // Maximum number of transmission retries
// before the packet is dropped.
Time m_slotTime; // Length of one slot. A slot time, it usually
// the packet transmission time, if the packet
// size is fixed.
Backoff();
Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
uint32_t ceiling, uint32_t maxRetries);
/**
* \return The amount of time that the net device should wait before
* trying to retransmit the packet
*/
Time GetBackoffTime();
/**
* Indicates to the backoff object that the last packet was
* successfully transmitted and that the number of retries should be
* reset to 0.
*/
void ResetBackoffTime();
/**
* \return True if the maximum number of retries has been reached
*/
bool MaxRetriesReached();
/**
* Increments the number of retries by 1.
*/
void IncrNumRetries();
private:
uint32_t m_numBackoffRetries; // Number of times that the
// transmitter has tried to
// unsuccessfully transmit the current
// packet
};
}; // namespace ns3
#endif // BACKOFF_H

View File

@@ -0,0 +1,359 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise
* All rights reserved.
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include "csma-cd-channel.h"
#include "csma-cd-net-device.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"
#include "ns3/debug.h"
NS_DEBUG_COMPONENT_DEFINE ("CsmaCdChannel");
namespace ns3 {
CsmaCdDeviceRec::CsmaCdDeviceRec()
{
active = false;
}
CsmaCdDeviceRec::CsmaCdDeviceRec(Ptr<CsmaCdNetDevice> device)
{
devicePtr = device;
active = true;
}
bool
CsmaCdDeviceRec::IsActive() {
return active;
}
//
// By default, you get a channel with the name "CsmaCd Channel" that
// has an "infitely" fast transmission speed and zero delay.
CsmaCdChannel::CsmaCdChannel()
:
Channel ("CsmaCd Channel"),
m_bps (DataRate(0xffffffff)),
m_delay (Seconds(0))
{
NS_DEBUG("CsmaCdChannel::CsmaCdChannel ()");
Init();
}
CsmaCdChannel::CsmaCdChannel(
const DataRate& bps,
const Time& delay)
:
Channel ("CsmaCd Channel"),
m_bps (bps),
m_delay (delay)
{
NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << Channel::GetName()
<< ", " << bps.GetBitRate() << ", " << delay << ")");
Init();
}
CsmaCdChannel::CsmaCdChannel(
const std::string& name,
const DataRate& bps,
const Time& delay)
:
Channel (name),
m_bps (bps),
m_delay (delay)
{
NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << name << ", " <<
bps.GetBitRate() << ", " << delay << ")");
Init();
}
void CsmaCdChannel::Init() {
m_state = IDLE;
m_deviceList.clear();
}
int32_t
CsmaCdChannel::Attach(Ptr<CsmaCdNetDevice> device)
{
NS_DEBUG("CsmaCdChannel::Attach (" << device << ")");
NS_ASSERT(device != 0);
CsmaCdDeviceRec rec(device);
m_deviceList.push_back(rec);
return (m_deviceList.size() - 1);
}
bool
CsmaCdChannel::Reattach(Ptr<CsmaCdNetDevice> device)
{
NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")");
NS_ASSERT(device != 0);
std::vector<CsmaCdDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if (it->devicePtr == device)
{
if (!it->active) {
it->active = true;
return true;
} else {
return false;
}
}
}
return false;
}
bool
CsmaCdChannel::Reattach(uint32_t deviceId)
{
NS_DEBUG("CsmaCdChannel::Reattach (" << deviceId << ")");
if (deviceId < m_deviceList.size())
{
return false;
}
if (m_deviceList[deviceId].active)
{
return false;
} else {
m_deviceList[deviceId].active = true;
return true;
}
}
bool
CsmaCdChannel::Detach(uint32_t deviceId)
{
NS_DEBUG("CsmaCdChannel::Detach (" << deviceId << ")");
if (deviceId < m_deviceList.size())
{
if (!m_deviceList[deviceId].active)
{
NS_DEBUG("CsmaCdChannel::Detach Device is already detached ("
<< deviceId << ")");
return false;
}
m_deviceList[deviceId].active = false;
if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
{
NS_DEBUG("CsmaCdChannel::Detach Device is currently"
<< "transmitting (" << deviceId << ")");
// Here we will need to place a warning in the packet
}
return true;
} else {
return false;
}
}
bool
CsmaCdChannel::Detach(Ptr<CsmaCdNetDevice> device)
{
NS_DEBUG("CsmaCdChannel::Detach (" << device << ")");
NS_ASSERT(device != 0);
std::vector<CsmaCdDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if ((it->devicePtr == device) && (it->active))
{
it->active = false;
return true;
}
}
return false;
}
bool
CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId)
{
NS_DEBUG ("CsmaCdChannel::TransmitStart (" << &p << ", " << srcId
<< ")");
NS_DEBUG ("CsmaCdChannel::TransmitStart (): UID is " <<
p.GetUid () << ")");
if (m_state != IDLE)
{
NS_DEBUG("CsmaCdChannel::TransmitStart (): state is not IDLE");
return false;
}
if (!IsActive(srcId))
{
NS_DEBUG("CsmaCdChannel::TransmitStart (): ERROR: Seclected "
<< "source is not currently attached to network");
return false;
}
NS_DEBUG("CsmaCdChannel::TransmitStart (): switch to TRANSMITTING");
m_currentPkt = p;
m_currentSrc = srcId;
m_state = TRANSMITTING;
return true;
}
bool
CsmaCdChannel::IsActive(uint32_t deviceId) {
return (m_deviceList[deviceId].active);
}
bool
CsmaCdChannel::TransmitEnd()
{
NS_DEBUG("CsmaCdChannel::TransmitEnd (" << &m_currentPkt << ", "
<< m_currentSrc << ")");
NS_DEBUG("CsmaCdChannel::TransmitEnd (): UID is " <<
m_currentPkt.GetUid () << ")");
NS_ASSERT(m_state == TRANSMITTING);
m_state = PROPAGATING;
bool retVal = true;
if (!IsActive(m_currentSrc)) {
NS_DEBUG("CsmaCdChannel::TransmitEnd (): ERROR: Seclected source "
<< "was detached before the end of the transmission");
retVal = false;
}
NS_DEBUG ("CsmaCdChannel::TransmitEnd (): Schedule event in " <<
m_delay.GetSeconds () << "sec");
Simulator::Schedule (m_delay,
&CsmaCdChannel::PropagationCompleteEvent,
this);
return retVal;
}
void
CsmaCdChannel::PropagationCompleteEvent()
{
NS_DEBUG("CsmaCdChannel::PropagationCompleteEvent ("
<< &m_currentPkt << ")");
NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): UID is " <<
m_currentPkt.GetUid () << ")");
NS_ASSERT(m_state == PROPAGATING);
m_state = IDLE;
NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive");
std::vector<CsmaCdDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if (it->IsActive())
{
it->devicePtr->Receive (m_currentPkt);
}
}
}
uint32_t
CsmaCdChannel::GetNumActDevices (void)
{
int numActDevices = 0;
std::vector<CsmaCdDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if (it->active)
{
numActDevices++;
}
}
return numActDevices;
}
// This is not the number of active devices. This is the total number
// of devices even if some were detached after.
uint32_t
CsmaCdChannel::GetNDevices (void) const
{
return (m_deviceList.size());
}
Ptr<NetDevice>
CsmaCdChannel::GetDevice (uint32_t i) const
{
Ptr< CsmaCdNetDevice > netDevice;
netDevice = m_deviceList[i].devicePtr;
return netDevice;
}
int32_t
CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
{
std::vector<CsmaCdDeviceRec>::iterator it;
int i = 0;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if (it->devicePtr == device)
{
if (it->active)
{
return i;
} else {
return -2;
}
}
i++;
}
return -1;
}
bool
CsmaCdChannel::IsBusy (void)
{
if (m_state == IDLE)
{
return false;
} else {
return true;
}
}
DataRate
CsmaCdChannel::GetDataRate (void)
{
return m_bps;
}
Time
CsmaCdChannel::GetDelay (void)
{
return m_delay;
}
WireState
CsmaCdChannel::GetState(void)
{
return m_state;
}
} // namespace ns3

View File

@@ -0,0 +1,307 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise
*
* 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: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
*/
#ifndef CSMA_CD_CHANNEL_H
#define CSMA_CD_CHANNEL_H
#include "ns3/channel.h"
#include "ns3/ptr.h"
#include "ns3/packet.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
namespace ns3 {
class CsmaCdNetDevice;
/**
* \brief CsmaCdNetDevice Record
*
* Stores the information related to each net device that is
* connected to the channel.
*/
class CsmaCdDeviceRec {
public:
Ptr< CsmaCdNetDevice > devicePtr; /// Pointer to the net device
bool active; /// Is net device enabled to TX/RX
CsmaCdDeviceRec();
CsmaCdDeviceRec(Ptr< CsmaCdNetDevice > device);
/*
* \return If the net device pointed to by the devicePtr is active
* and ready to RX/TX.
*/
bool IsActive();
};
/**
* Current state of the channel
*/
enum WireState
{
IDLE, /**< Channel is IDLE, no packet is being
transmitted */
TRANSMITTING, /**< Channel is BUSY, a packet is being written
by a net device */
PROPAGATING /**< Channel is BUSY, packet is propagating to
all attached net devices */
};
/**
* \brief CsmaCd Channel.
*
* This class represents a simple Csma/Cd channel that can be used
* when many nodes are connected to one wire. It uses a single busy
* flag to indicate if the channel is currently in use. It does not
* take into account the distances between stations or the speed of
* light to determine collisions.
*
* Each net device must query the state of the channel and make sure
* that it is IDLE before writing a packet to the channel.
*
* When the channel is instaniated, the constructor takes parameters
* for a single speed, in bits per second, and a speed-of-light delay
* time as a Time object. When a net device is attached to a channel,
* it is assigned a device ID, this is in order to facilitate the
* check that makes sure that a net device that is trying to send a
* packet to the channel is really connected to this channel
*
*/
class CsmaCdChannel : public Channel {
public:
/**
* \brief Create a CsmaCdChannel
*
* By default, you get a channel with the name "CsmaCd Channel" that
* has an "infitely" fast transmission speed and zero delay.
*/
CsmaCdChannel ();
/**
* \brief Create a CsmaCdChannel
*
* \param bps The bitrate of the channel
* \param delay Transmission delay through the channel
*/
CsmaCdChannel (const DataRate& bps, const Time& delay);
/**
* \brief Create a CsmaCdChannel
*
* \param name the name of the channel for identification purposes
* \param bps The bitrate of the channel
* \param delay Transmission delay through the channel
*/
CsmaCdChannel (const std::string& name,
const DataRate& bps, const Time& delay);
/**
* \brief Attach a given netdevice to this channel
*
* \param device Device pointer to the netdevice to attach to the channel
* \return The assigned device number
*/
int32_t Attach (Ptr<CsmaCdNetDevice> device);
/**
* \brief Detach a given netdevice from this channel
*
* The net device is marked as inactive and it is not allowed to
* receive or transmit packets
*
* \param device Device pointer to the netdevice to detach from the channel
* \return True if the device is found and attached to the channel,
* false if the device is not currently connected to the channel or
* can't be found.
*/
bool Detach (Ptr<CsmaCdNetDevice> device);
/**
* \brief Detach a given netdevice from this channel
*
* The net device is marked as inactive and it is not allowed to
* receive or transmit packets
*
* \param deviceId The deviceID assigned to the net device when it
* was connected to the channel
* \return True if the device is found and attached to the channel,
* false if the device is not currently connected to the channel or
* can't be found.
*/
bool Detach (uint32_t deviceId);
/**
* \brief Reattach a previously detached net device to the channel
*
* The net device is marked as active. It is now allowed to receive
* or transmit packets. The net device must have been previously
* attached to the channel using the attach function.
*
* \param deviceId The device ID assigned to the net device when it
* was connected to the channel
* \return True if the device is found and is not attached to the
* channel, false if the device is currently connected to the
* channel or can't be found.
*/
bool Reattach(uint32_t deviceId);
/**
* \brief Reattach a previously detached net device to the channel
*
* The net device is marked as active. It is now allowed to receive
* or transmit packets. The net device must have been previously
* attached to the channel using the attach function.
*
* \param device Device pointer to the netdevice to detach from the channel
* \return True if the device is found and is not attached to the
* channel, false if the device is currently connected to the
* channel or can't be found.
*/
bool Reattach(Ptr<CsmaCdNetDevice> device);
/**
* \brief Start transmitting a packet over the channel
*
* If the srcId belongs to a net device that is connected to the
* channel, packet transmission begins, and the channel becomes busy
* until the packet has completely reached all destinations.
*
* \param p A reference to the packet that will be transmitted over
* the channel
* \param srcId The device Id of the net device that wants to
* transmit on the channel.
* \return True if the channel is not busy and the transmitting net
* device is currently active.
*/
bool TransmitStart (Packet& p, uint32_t srcId);
/**
* \brief Indicates that the net device has finished transmitting
* the packet over the channel
*
* The channel will stay busy until the packet has completely
* propagated to all net devices attached to the channel. The
* TransmitEnd function schedules the PropagationCompleteEvent which
* will free the channel for further transmissions. Stores the
* packet p as the m_currentPkt, the packet being currently
* transmitting.
*
* \return Returns true unless the source was detached before it
* completed its transmission.
*/
bool TransmitEnd ();
/**
* \brief Indicates that the channel has finished propagating the
* current packet. The channel is released and becomes free.
*
* Calls the receive function of every active net device that is
* attached to the channel.
*/
void PropagationCompleteEvent();
/**
* \return Returns the device number assigned to a net device by the
* channel
*
* \param device Device pointer to the netdevice for which the device
* number is needed
*/
int32_t GetDeviceNum (Ptr<CsmaCdNetDevice> device);
/**
* \return Returns the state of the channel (IDLE -- free,
* TRANSMITTING -- busy, PROPAGATING - busy )
*/
WireState GetState();
/**
* \brief Indicates if the channel is busy. The channel will only
* accept new packets for transmission if it is not busy.
*
* \return Returns true if the channel is busy and false if it is
* free.
*/
bool IsBusy();
/**
* \brief Indicates if a net device is currently attached or
* detached from the channel.
*
* \param deviceId The ID that was assigned to the net device when
* it was attached to the channel.
* \return Returns true if the net device is attached to the
* channel, false otherwise.
*/
bool IsActive(uint32_t deviceId);
/**
* \return Returns the number of net devices that are currently
* attached to the channel.
*/
uint32_t GetNumActDevices (void);
/**
* \return Returns the total number of devices including devices
* that have been detached from the channel.
*/
virtual uint32_t GetNDevices (void) const;
/**
* \param i The deviceId of the net device for which we want the
* pointer.
* \return Returns the pointer to the net device that is associated
* with deviceId i.
*/
virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
virtual DataRate GetDataRate (void);
virtual Time GetDelay (void);
private:
DataRate m_bps; /// Data rate of the channel
Time m_delay; /// Delay of the channel.
/**
* List of the net devices that have been or are currently connected
* to the channel.
*
* Devices are nor removed from this list, they are marked as
* inactive. Otherwise the assigned device IDs will not refer to the
* correct NetDevice. The DeviceIds are used so that it is possible
* to have a number to refer to an entry in the list so that the
* whole list does not have to be searched when making sure that a
* source is attached to a channel when it is transmitting data.
*/
std::vector< CsmaCdDeviceRec > m_deviceList;
/**
* Packet that is currently being transmitted on the channel (or last
* packet to have been transmitted on the channel if the channel is
* free.)
*/
Packet m_currentPkt;
/**
* Device Id of the source that is currently transmitting on the
* channel. Or last source to have transmitted a packet on the
* channel, if the channel is currently not busy.
*/
uint32_t m_currentSrc;
/**
* Current state of the channel
*/
WireState m_state;
/**
* Initializes the channel when it is constructed. Resets the
* deviceList and sets the channel state to IDLE.
*/
void Init (void);
};
} // namespace ns3
#endif /* CSMA_CD_CHANNEL_H */

View File

@@ -0,0 +1,162 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2007 Emmanuelle Laprise
//
// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
//
#include <algorithm>
#include "ns3/assert.h"
#include "ns3/debug.h"
#include "ns3/fatal-error.h"
#include "ns3/nstime.h"
#include "ns3/internet-node.h"
#include "ns3/ipv4-address.h"
#include "ns3/ipv4.h"
#include "ns3/queue.h"
#include "csma-cd-channel.h"
#include "csma-cd-net-device.h"
#include "csma-cd-ipv4-topology.h"
namespace ns3 {
void
CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
// Use the first net device in the node to transmit
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::IP_ARP,
true, false);
nd0->AddQueue(q);
nd0->Attach (ch);
// Use the second net device in the node to transmit
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::IP_ARP,
false, true);
nd1->AddQueue(q);
nd1->Attach (ch);
}
void
CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::LLC,
true, false);
nd0->AddQueue(q);
nd0->Attach (ch);
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::LLC,
false, true);
nd1->AddQueue(q);
nd1->Attach (ch);
}
void
CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::RAW,
true, false);
nd0->AddQueue(q);
nd0->Attach (ch);
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::RAW,
false, true);
nd1->AddQueue(q);
nd1->Attach (ch);
}
void
CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> n1,
int ndNum,
const Ipv4Address& addr1,
const Ipv4Mask& netmask1)
{
// Duplex link is assumed to be subnetted as a /30
// May run this unnumbered in the future?
Ipv4Mask netmask(netmask1);
Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
uint32_t index1 = ip1->AddInterface (nd1);
ip1->SetAddress (index1, addr1);
ip1->SetNetworkMask (index1, netmask);
ip1->SetUp (index1);
}
void
CsmaCdIpv4Topology::AddIpv4Routes (
Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
{
// Assert that both are Ipv4 nodes
Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
NS_ASSERT(ip1 != 0 && ip2 != 0);
// Get interface indexes for both nodes corresponding to the right channel
uint32_t index1 = 0;
bool found = false;
for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
{
if (ip1 ->GetNetDevice (i) == nd1)
{
index1 = i;
found = true;
}
}
NS_ASSERT(found);
uint32_t index2 = 0;
found = false;
for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
{
if (ip2 ->GetNetDevice (i) == nd2)
{
index2 = i;
found = true;
}
}
NS_ASSERT(found);
ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2);
}
} // namespace ns3

View File

@@ -0,0 +1,120 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2007 Emmanuelle Laprise
//
// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
//
#ifndef __CSMA_CD_IPV4_TOPOLOGY_H__
#define __CSMA_CD_IPV4_TOPOLOGY_H__
#include "ns3/ptr.h"
#include "ns3/ipv4-address.h"
#include "ns3/ipv4.h"
#include "ns3/ipv4-route.h"
#include "ns3/internet-node.h"
#include "ns3/csma-cd-net-device.h"
// The topology class consists of only static methods thar are used to
// create the topology and data flows for an ns3 simulation
namespace ns3 {
class CsmaCdIpv4Channel;
class Node;
class IPAddr;
class DataRate;
class Queue;
/**
* \brief A helper class to create Topologies based on the
* InternetNodes and CsmaCdChannels. Either the
* SimpleCsmaCdNetDevice or the LLCCsmaCdNetDevice can be used
* when constructing these topologies.
*/
class CsmaCdIpv4Topology {
public:
/**
* \param n1 Node to be attached to the Csma/Cd channel
* \param ch CsmaCdChannel to which node n1 should be attached
* \param addr Mac address of the node
*
* Add a Csma/Cd node to a Csma/Cd channel. This function adds
* a EthernetCsmaCdNetDevice to the nodes so that they can
* connect to a CsmaCdChannel. This means that Ethernet headers
* and trailers will be added to the packet before sending out on
* the net device.
*/
static void AddIpv4CsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr);
/**
* \param n1 Node to be attached to the Csma/Cd channel
* \param ch CsmaCdChannel to which node n1 should be attached
* \param addr Mac address of the node
*
* Add a Csma/Cd node to a Csma/Cd channel. This function adds
* a RawCsmaCdNetDevice to the nodes so that they can connect
* to a CsmaCdChannel.
*/
static void AddIpv4RawCsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr);
/**
* \param n1 Node to be attached to the Csma/Cd channel
* \param ch CsmaCdChannel to which node n1 should be attached
* \param addr Mac address of the node
*
* Add a Csma/Cd node to a Csma/Cd channel. This function adds
* a LlcCsmaCdNetDevice to the nodes so that they can connect
* to a CsmaCdChannel.
*/
static void AddIpv4LlcCsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr);
/**
* \param n1 Node
* \param ndNum NetDevice number with which to associate address
* \param addr1 Ipv4 Address for ndNum of n1
* \param network network mask for ndNum of node n1
*
* Add an Ipv4Address to the Ipv4 interface associated with the
* ndNum CsmaCdIpv4NetDevices on the provided
* CsmaCdIpv4Channel
*/
static void AddIpv4Address(Ptr<Node> n1, int ndNum,
const Ipv4Address& addr1,
const Ipv4Mask& netmask1);
/**
* \param nd1 Node
* \param nd2 Node
*
* Add an IPV4 host route between the two specified net devices
*/
static void AddIpv4Routes (Ptr<NetDevice> nd1, Ptr<NetDevice> nd2);
};
} // namespace ns3
#endif

View File

@@ -0,0 +1,504 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise
* All rights reserved.
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include <iostream>
#include <cassert>
#include "ns3/debug.h"
#include "ns3/queue.h"
#include "ns3/simulator.h"
#include "ns3/composite-trace-resolver.h"
#include "csma-cd-net-device.h"
#include "csma-cd-channel.h"
#include "ns3/ethernet-header.h"
#include "ns3/ethernet-trailer.h"
#include "ns3/llc-snap-header.h"
NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice");
namespace ns3 {
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
CsmaCdEncapsulationMode pktType)
: NetDevice(node, addr), m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
m_pktType = pktType;
Init(true, true);
}
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
CsmaCdEncapsulationMode pktType,
bool sendEnable, bool receiveEnable)
: NetDevice(node, addr), m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
m_pktType = pktType;
Init(sendEnable, receiveEnable);
}
CsmaCdNetDevice::~CsmaCdNetDevice()
{
NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
m_queue = 0;
}
//
// Copy constructor for CsmaCdNetDevice.
//
// We use the underlying NetDevice copy constructor to get the base class
// copied. These just remain as is (e.g. you get the same name, the same
// MAC address). If you need to fix them up, YOU, the copier need to do
// that.
//
// The things we need to be careful of are the channel, the queue and the
// trace callback. If the channel pointer is non-zero, we copy the pointer
// and add a reference. If the queue is non-zero, we copy it using the queue
// assignment operator. We don't mess with the trace -- we just reset it.
// We're assuming that the tracing will be set up after the topology creation
// phase and this won't actually matter.
//
CsmaCdNetDevice::CsmaCdNetDevice (const CsmaCdNetDevice& nd)
: NetDevice(nd), m_bps (nd.m_bps)
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << &nd << ")");
m_txMachineState = READY;
m_tInterframeGap = nd.m_tInterframeGap;
m_backoff = nd.m_backoff;
m_channel = nd.m_channel;
m_queue = 0;
m_pktType = nd.m_pktType;
m_sendEnable = nd.m_sendEnable;
m_receiveEnable = nd.m_receiveEnable;
if (nd.m_queue)
{
m_queue = nd.m_queue;
}
}
void
CsmaCdNetDevice::DoDispose ()
{
m_channel = 0;
NetDevice::DoDispose ();
}
//
// Assignment operator for CsmaCdNetDevice.
//
// This uses the non-obvious trick of taking the source net device passed by
// value instead of by reference. This causes the copy constructor to be
// invoked (where the real work is done -- see above). All we have to do
// here is to return the newly constructed net device.
//
/*
CsmaCdNetDevice&
CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd)
{
NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")");
return *this;
}
*/
void
CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
{
m_txMachineState = READY;
m_tInterframeGap = Seconds(0);
m_channel = 0;
m_queue = 0;
EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
EnableMulticast();
EnablePointToPoint();
SetSendEnable (sendEnable);
SetReceiveEnable (receiveEnable);
}
void
CsmaCdNetDevice::SetSendEnable (bool sendEnable)
{
m_sendEnable = sendEnable;
}
void
CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable)
{
m_receiveEnable = receiveEnable;
}
bool
CsmaCdNetDevice::IsSendEnabled (void)
{
return (m_sendEnable);
}
bool
CsmaCdNetDevice::IsReceiveEnabled (void)
{
return (m_receiveEnable);
}
void
CsmaCdNetDevice::SetDataRate (DataRate bps)
{
m_bps = bps;
}
void
CsmaCdNetDevice::SetInterframeGap (Time t)
{
m_tInterframeGap = t;
}
void
CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
uint32_t maxSlots, uint32_t ceiling,
uint32_t maxRetries)
{
m_backoff.m_slotTime = slotTime;
m_backoff.m_minSlots = minSlots;
m_backoff.m_maxSlots = maxSlots;
m_backoff.m_ceiling = ceiling;
m_backoff.m_maxRetries = maxRetries;
}
void
CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest,
uint16_t protocolNumber)
{
if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP))
{
EthernetHeader header;
EthernetTrailer trailer;
header.SetSource(this->GetAddress());
header.SetDestination(dest);
switch (m_pktType)
{
case IP_ARP:
header.SetLengthType(protocolNumber);
break;
default:
header.SetLengthType(p.GetSize() + header.GetSize() + trailer.GetSize());
break;
}
p.AddHeader(header);
trailer.CalcFcs(p);
p.AddTrailer(trailer);
}
else if (m_pktType == LLC)
{
LlcSnapHeader llc;
llc.SetType (protocolNumber);
p.AddHeader (llc);
}
}
bool
CsmaCdNetDevice::ProcessHeader(Packet& p, int& param)
{
bool retVal = true;
if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP))
{
EthernetHeader header;
EthernetTrailer trailer;
p.RemoveTrailer(trailer);
trailer.CheckFcs(p);
p.RemoveHeader(header);
param = header.GetLengthType();
if ((header.GetDestination() != this->GetBroadcast()) &&
(header.GetDestination() != this->GetAddress()))
{
retVal = false;
}
}
else if (m_pktType == LLC)
{
LlcSnapHeader llc;
p.RemoveHeader (llc);
param = llc.GetType ();
}
return retVal;
}
bool
CsmaCdNetDevice::DoNeedsArp (void) const
{
if ((m_pktType == IP_ARP) || (m_pktType == LLC))
{
return true;
} else {
return false;
}
}
bool
CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber)
{
NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
NS_ASSERT (IsLinkUp ());
// Only transmit if send side of net device is enabled
if (!IsSendEnabled())
return false;
AddHeader(p, dest, protocolNumber);
// Place the packet to be sent on the send queue
if (m_queue->Enqueue(p) == false )
{
return false;
}
// If the device is idle, we need to start a transmission. Otherwise,
// the transmission will be started when the current packet finished
// transmission (see TransmitCompleteEvent)
if (m_txMachineState == READY)
{
// Store the next packet to be transmitted
if (m_queue->Dequeue (m_currentPkt))
{
TransmitStart();
}
}
return true;
}
void
CsmaCdNetDevice::TransmitStart ()
{
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")");
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is "
<< m_currentPkt.GetUid () << ")");
//
// This function is called to start the process of transmitting a packet.
// We need to tell the channel that we've started wiggling the wire and
// schedule an event that will be executed when it's time to tell the
// channel that we're done wiggling the wire.
//
NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF),
"Must be READY to transmit. Tx state is: "
<< m_txMachineState);
// Only transmit if send side of net device is enabled
if (!IsSendEnabled())
return;
if (m_channel->GetState() != IDLE)
{ // Channel busy, backoff and rechedule TransmitStart()
m_txMachineState = BACKOFF;
if (m_backoff.MaxRetriesReached())
{ // Too many retries reached, abort transmission of packet
TransmitAbort();
} else {
m_backoff.IncrNumRetries();
Time backoffTime = m_backoff.GetBackoffTime();
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): "
<< "Channel busy, backing off for "
<< backoffTime.GetSeconds () << "sec");
Simulator::Schedule (backoffTime,
&CsmaCdNetDevice::TransmitStart,
this);
}
} else {
// Channel is free, transmit packet
m_txMachineState = BUSY;
Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
"Schedule TransmitCompleteEvent in " <<
tEvent.GetSeconds () << "sec");
Simulator::Schedule (tEvent,
&CsmaCdNetDevice::TransmitCompleteEvent,
this);
if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
{
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
"Channel transmit start did not work at " <<
tEvent.GetSeconds () << "sec");
m_txMachineState = READY;
} else {
// Transmission success, reset backoff time parameters.
m_backoff.ResetBackoffTime();
}
}
}
void
CsmaCdNetDevice::TransmitAbort (void)
{
NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()");
NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " <<
m_currentPkt.GetUid () << ")");
// Try to transmit a new packet
bool found;
found = m_queue->Dequeue (m_currentPkt);
NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
m_backoff.ResetBackoffTime();
m_txMachineState = READY;
TransmitStart ();
}
void
CsmaCdNetDevice::TransmitCompleteEvent (void)
{
NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()");
//
// This function is called to finish the process of transmitting a packet.
// We need to tell the channel that we've stopped wiggling the wire and
// schedule an event that will be executed when it's time to re-enable
// the transmitter after the interframe gap.
//
NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
// Channel should be transmitting
NS_ASSERT(m_channel->GetState() == TRANSMITTING);
m_txMachineState = GAP;
NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
m_currentPkt.GetUid () << ")");
m_channel->TransmitEnd ();
NS_DEBUG (
"CsmaCdNetDevice::TransmitCompleteEvent (): " <<
"Schedule TransmitReadyEvent in "
<< m_tInterframeGap.GetSeconds () << "sec");
Simulator::Schedule (m_tInterframeGap,
&CsmaCdNetDevice::TransmitReadyEvent,
this);
}
void
CsmaCdNetDevice::TransmitReadyEvent (void)
{
NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()");
//
// This function is called to enable the transmitter after the interframe
// gap has passed. If there are pending transmissions, we use this opportunity
// to start the next transmit.
//
NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
m_txMachineState = READY;
// Get the next packet from the queue for transmitting
if (m_queue->IsEmpty())
{
return;
}
else
{
bool found;
found = m_queue->Dequeue (m_currentPkt);
NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
TransmitStart ();
}
}
TraceResolver *
CsmaCdNetDevice::DoCreateTraceResolver (TraceContext const &context)
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
resolver->Add ("queue",
MakeCallback (&Queue::CreateTraceResolver,
PeekPointer (m_queue)),
CsmaCdNetDevice::QUEUE);
resolver->Add ("rx",
m_rxTrace,
CsmaCdNetDevice::RX);
return resolver;
}
bool
CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
{
NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")");
m_channel = ch;
m_deviceId = m_channel->Attach(this);
m_bps = m_channel->GetDataRate ();
m_tInterframeGap = m_channel->GetDelay ();
/*
* For now, this device is up whenever a channel is attached to it.
*/
NotifyLinkUp ();
return true;
}
void
CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
{
NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")");
m_queue = q;
}
void
CsmaCdNetDevice::Receive (Packet& p)
{
NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
// Only receive if send side of net device is enabled
if (!IsReceiveEnabled())
return;
int param = 0;
Packet packet = p;
if (ProcessHeader(packet, param))
{
m_rxTrace (packet);
ForwardUp (packet, param);
} else {
m_dropTrace (packet);
}
}
Ptr<Queue>
CsmaCdNetDevice::GetQueue(void) const
{
return m_queue;
}
Ptr<Channel>
CsmaCdNetDevice::DoGetChannel(void) const
{
return m_channel;
}
} // namespace ns3

View File

@@ -0,0 +1,424 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
* Derived from the p2p net device file
*/
#ifndef CSMA_CD_NET_DEVICE_H
#define CSMA_CD_NET_DEVICE_H
#include <string.h>
#include "ns3/node.h"
#include "ns3/backoff.h"
#include "ns3/mac-address.h"
#include "ns3/net-device.h"
#include "ns3/callback.h"
#include "ns3/packet.h"
#include "ns3/callback-trace-source.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
namespace ns3 {
class Queue;
class CsmaCdChannel;
/**
* \class CsmaCdNetDevice
* \brief A Device for a CsmaCd Network Link.
*
* The Csma/Cd net device class is analogous to layer 1 and 2 of the
* TCP stack. The NetDevice takes a raw packet of bytes and creates a
* protocol specific packet from them. The Csma/Cd net device class
* takes this packet and adds and processes the headers/trailers that
* are associated with EthernetV1, EthernetV2, RAW or LLC
* protocols. The EthernetV1 packet type adds and removes Ethernet
* destination and source addresses. The LLC packet type adds and
* removes LLC snap headers. The raw packet type does not add or
* remove any headers. Each Csma/Cd net device will receive all
* packets written to the Csma/Cd link. The ProcessHeader function can
* be used to filter out the packets such that higher level layers
* only receive packets that are addressed to their associated net
* devices
*
*/
class CsmaCdNetDevice : public NetDevice {
public:
/**
* Enumeration of the types of traces supported in the class.
*
*/
enum TraceType {
QUEUE, /**< Trace queue events on the attached queue */
RX, /**< Trace packet reception events (from the channel) */
DROP /**< Trace packet drop events (from the channel) */
};
/**
* Enumeration of the types of packets supported in the class.
*
*/
enum CsmaCdEncapsulationMode {
ETHERNET_V1, /**< Version one ethernet packet, length field */
IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */
RAW, /**< Packet that contains no headers */
LLC, /**< LLC packet encapsulation */
};
/**
* Construct a CsmaCdNetDevice
*
* This is the constructor for the CsmaCdNetDevice. It takes as a
* parameter the Node to which this device is connected. Ownership of the
* Node pointer is not implied and the node must not be deleted.
*
* \param node the Node to which this device is connected.
* \param addr The source MAC address of the net device.
*/
CsmaCdNetDevice (Ptr<Node> node, MacAddress addr, CsmaCdEncapsulationMode pktType);
CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
CsmaCdEncapsulationMode pktType,
bool sendEnable, bool receiveEnable);
/**
* Copy Construct a CsmaCdNetDevice
*
* This is the copy constructor for the CsmaCdNetDevice. This is
* primarily used in topology creation.
*
* \param nd the object to be copied
*/
CsmaCdNetDevice (const CsmaCdNetDevice& nd);
/**
* Destroy a CsmaCdNetDevice
*
* This is the destructor for the CsmaCdNetDevice.
*/
virtual ~CsmaCdNetDevice();
/**
* Assignment Operator for a CsmaCdNetDevice
*
* This is the assignment operator for the CsmaCdNetDevice. This is
* to allow
*
* \param nd the object to be copied
*/
// CsmaCdNetDevice& operator= (CsmaCdNetDevice nd);
/**
* Set the Data Rate used for transmission of packets. The data rate is
* set in the Attach () method from the corresponding field in the channel
* to which the device is attached. It can be overridden using this method.
*
* @see Attach ()
* \param bps the data rate at which this object operates
*/
void SetDataRate (DataRate bps);
/**
* Set the inteframe gap used to separate packets. The interframe gap
* defines the minimum space required between packets sent by this device.
* It is usually set in the Attach () method based on the speed of light
* delay of the channel to which the device is attached. It can be
* overridden using this method if desired.
*
* @see Attach ()
* \param t the interframe gap time
*/
void SetInterframeGap (Time t);
/**
* Set the backoff parameters used to determine the wait to retry
* transmitting a packet when the channel is busy.
*
* @see Attach ()
* \param slotTime Length of a packet slot (or average packet time)
* \param minSlots Minimum number of slots to wait
* \param maxSlots Maximum number of slots to wait
* \param maxRetries Maximum number of retries before packet is discard
* \param ceiling Cap on the exponential function when calculating max slots
*/
void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots,
uint32_t maxRetries, uint32_t ceiling);
/**
* Attach the device to a channel.
*
* The function Attach is used to add a CsmaCdNetDevice to a
* CsmaCdChannel.
*
* @see SetDataRate ()
* @see SetInterframeGap ()
* \param ch a pointer to the channel to which this object is being attached.
*/
bool Attach (Ptr<CsmaCdChannel> ch);
/**
* Attach a queue to the CsmaCdNetDevice.
*
* The CsmaCdNetDevice "owns" a queue. This queue is created by the
* CsmaCdTopology object and implements a queueing method such as
* DropTail or RED. The CsmaCdNetDevice assumes ownership of this
* queue and must delete it when the device is destroyed.
*
* @see CsmaCdTopology::AddCsmaCdLink ()
* @see Queue
* @see DropTailQueue
* \param queue a pointer to the queue for which object is assuming
* ownership.
*/
void AddQueue (Ptr<Queue> queue);
/**
* Receive a packet from a connected CsmaCdChannel.
*
* The CsmaCdNetDevice receives packets from its connected channel
* and forwards them up the protocol stack. This is the public method
* used by the channel to indicate that the last bit of a packet has
* arrived at the device.
*
* @see CsmaCdChannel
* \param p a reference to the received packet
*/
void Receive (Packet& p);
bool IsSendEnabled (void);
bool IsReceiveEnabled (void);
void SetSendEnable (bool);
void SetReceiveEnable (bool);
protected:
virtual bool DoNeedsArp (void) const;
virtual void DoDispose (void);
/**
* Get a copy of the attached Queue.
*
* This method is provided for any derived class that may need to get
* direct access to the underlying queue.
*
* \return a pointer to the queue.
*/
Ptr<Queue> GetQueue (void) const;
/**
* Get a copy of the attached Channel
*
* This method is provided for any derived class that may need to get
* direct access to the connected channel
*
* \return a pointer to the channel
*/
virtual Ptr<Channel> DoGetChannel (void) const;
/**
* Adds the necessary headers and trailers to a packet of data in order to
* respect the packet type
*
* \param p Packet to which header should be added
* \param dest MAC destination address to which packet should be sent
* \param protocolNumber In some protocols, identifies the type of
* payload contained in this packet.
*/
void AddHeader (Packet& p, const MacAddress& dest,
uint16_t protocolNumber);
/**
* Removes, from a packet of data, all headers and trailers that
* relate to the packet type
*
* \param p Packet whose headers need to be processed
* \param param An integer parameter that can be set by the function
* to return information gathered in the header
* \return Returns true if the packet should be forwarded up the
* protocol stack.
*/
bool ProcessHeader (Packet& p, int& param);
private:
/**
* Initializes variablea when construction object.
*/
void Init (bool sendEnable, bool receiveEnable);
/**
* Send a Packet on the Csma/Cd network
*
* This method does not use a destination address since all packets
* are broadcast to all NetDevices attached to the channel. Packet
* should contain all needed headers at this time.
*
* If the device is ready to transmit, the next packet is read off
* of the queue and stored locally until it has been transmitted.
*
* \param p a reference to the packet to send
* \param dest destination address
* \param protocolNumber -- this parameter is not used here
* \return true if success, false on failure
*/
virtual bool SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber);
/**
* Start Sending a Packet Down the Wire.
*
* The TransmitStart method is the method that is used internally in
* the CsmaCdNetDevice to begin the process of sending a packet
* out on the channel. The corresponding method is called on the
* channel to let it know that the physical device this class
* represents has virually started sending signals, this causes the
* channel to become busy. An event is scheduled for the time at
* which the bits have been completely transmitted. If the channel
* is busy, the method reschedules itself for a later time (within
* the backoff period)
*
* @see CsmaCdChannel::TransmitStart ()
* @see TransmitCompleteEvent ()
*/
void TransmitStart ();
/**
* Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
*
* The TransmitCompleteEvent method is used internally to finish the process
* of sending a packet out on the channel. During execution of this method
* the TransmitEnd method is called on the channel to let it know that the
* physical device this class represents has virually finished sending
* signals. The channel uses this event to begin its speed of light delay
* timer after which it notifies the Net Device at the other end of the
* link that the bits have arrived. During this method, the net device
* also schedules the TransmitReadyEvent at which time the transmitter
* becomes ready to send the next packet.
*
* @see CsmaCdChannel::TransmitEnd ()
* @see TransmitReadyEvent ()
*/
void TransmitCompleteEvent (void);
/**
* Cause the Transmitter to Become Ready to Send Another Packet.
*
* The TransmitReadyEvent method is used internally to re-enable the
* transmit machine of the net device. It is scheduled after a suitable
* interframe gap after the completion of the previous transmission.
* The queue is checked at this time, and if there is a packet waiting on
* the queue, the transmission process is begun.
*
* If a packet is in the queue, it is extracted for the queue as the
* next packet to be transmitted by the net device.
*
* @see TransmitStart ()
*/
void TransmitReadyEvent (void);
/**
* Create a Trace Resolver for events in the net device.
* (NOT TESTED)
* @see class TraceResolver
*/
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
/**
* Aborts the transmission of the current packet
*
* If the net device has tried to transmit a packet for more times
* than the maximum allowed number of retries (channel always busy)
* then the packet is dropped.
*
*/
void TransmitAbort (void);
/**
* Device ID returned by the attached functions. It is used by the
* mp-channel to identify each net device to make sure that only
* active net devices are writing to the channel
*/
uint32_t m_deviceId;
/**
* Enable net device to send packets. True by default
*/
bool m_sendEnable;
/**
* Enable net device to receive packets. True by default
*/
bool m_receiveEnable;
/**
* Enumeration of the states of the transmit machine of the net device.
*/
enum TxMachineState
{
READY, /**< The transmitter is ready to begin transmission of a packet */
BUSY, /**< The transmitter is busy transmitting a packet */
GAP, /**< The transmitter is in the interframe gap time */
BACKOFF /**< The transmitter is waiting for the channel to be free */
};
/**
* The state of the Net Device transmit state machine.
* @see TxMachineState
*/
TxMachineState m_txMachineState;
/**
* The type of packet that should be created by the AddHeader
* function and that should be processed by the ProcessHeader
* function.
*/
CsmaCdEncapsulationMode m_pktType;
/**
* The data rate that the Net Device uses to simulate packet transmission
* timing.
* @see class DataRate
*/
DataRate m_bps;
/**
* The interframe gap that the Net Device uses to throttle packet
* transmission
* @see class Time
*/
Time m_tInterframeGap;
/**
* Holds the backoff parameters and is used to calculate the next
* backoff time to use when the channel is busy and the net device
* is ready to transmit
*/
Backoff m_backoff;
/**
* Next packet that will be transmitted (if transmitter is not
* currently transmitting) or packet that is currently being
* transmitted.
*/
Packet m_currentPkt;
/**
* The CsmaCdChannel to which this CsmaCdNetDevice has been
* attached.
* @see class CsmaCdChannel
*/
Ptr<CsmaCdChannel> m_channel;
/**
* The Queue which this CsmaCdNetDevice uses as a packet source.
* Management of this Queue has been delegated to the CsmaCdNetDevice
* and it has the responsibility for deletion.
* @see class Queue
* @see class DropTailQueue
*/
Ptr<Queue> m_queue;
/**
* NOT TESTED
* The trace source for the packet reception events that the device can
* fire.
*
* @see class CallBackTraceSource
* @see class TraceResolver
*/
CallbackTraceSource<Packet &> m_rxTrace;
CallbackTraceSource<Packet &> m_dropTrace;
};
}; // namespace ns3
#endif // CSMA_CD_NET_DEVICE_H

View File

@@ -0,0 +1,103 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2007 Emmanuelle Laprise
//
// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
//
//
// Topology helper for CsmaCd channels in ns3.
#include "ns3/assert.h"
#include "ns3/debug.h"
#include "ns3/queue.h"
#include "csma-cd-channel.h"
#include "csma-cd-net-device.h"
#include "csma-cd-topology.h"
#include "ns3/socket-factory.h"
namespace ns3 {
Ptr<CsmaCdChannel>
CsmaCdTopology::CreateCsmaCdChannel(
const DataRate& bps,
const Time& delay)
{
Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (bps, delay);
return channel;
}
#if 0
Ptr<CsmaCdNetDevice>
CsmaCdTopology::AddCsmaCdEthernetNode(
Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr)
{
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::ETHERNET_V1);
Ptr<Queue> q = Queue::CreateDefault ();
nd1->AddQueue(q);
nd1->Attach (ch);
return nd1;
}
Ptr<PacketSocket>
CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
Ptr<CsmaCdNetDevice> ndDest)
{
Ptr<PacketSocket> socket = Create<PacketSocket> ();
socket->Bind(ndSrc);
socket->Connect(ndDest->GetAddress());
app->Connect(socket);
return socket;
}
Ptr<PacketSocket>
CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
MacAddress macAddr)
{
Ptr<PacketSocket> socket = Create<PacketSocket> ();
socket->Bind(ndSrc);
socket->Connect(macAddr);
app->Connect(socket);
return socket;
}
Ptr<Socket>
CsmaCdTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
{
InterfaceId iid = InterfaceId::LookupByName (iid_name);
Ptr<SocketFactory> socketFactory =
n1->QueryInterface<SocketFactory> (iid);
Ptr<Socket> socket = socketFactory->CreateSocket ();
return socket;
}
#endif
} // namespace ns3

View File

@@ -0,0 +1,128 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
//
// Copyright (c) 2007 Emmanuelle Laprise
//
// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
//
// Topology helper for multipoint channels in ns3.
//
#ifndef CSMA_CD_TOPOLOGY_H
#define CSMA_CD_TOPOLOGY_H
#include "ns3/ptr.h"
#include "ns3/csma-cd-net-device.h"
#if 0
#include "ns3/packet-socket.h"
#include "ns3/packet-socket-app.h"
#endif
#include "ns3/node.h"
#include "ns3/mac-address.h"
// The topology class consists of only static methods thar are used to
// create the topology and data flows for an ns3 simulation
namespace ns3 {
class CsmaCdChannel;
class Node;
class DataRate;
class Queue;
/**
* \brief A helper class to create CsmaCd Topologies
*
* CsmaCd topologies are created based on the
* ns3::CsmaCdNetDevice subclasses and ns3::CsmaCdChannel
* objects. This class uses the EthernetNetDevice and
* PacketSocket classes in order to create logical connections between
* net devices. The PacketSocket class generates the data and the
* EthernetNetDevice class creates ethernet packets from the
* data, filling in source and destination addresses. The
* EthernetNetDevice class filters received data packets
* according to its destination Mac addresses.
*/
class CsmaCdTopology {
public:
/**
* \param dataRate Maximum transmission link rate
* \param delay propagation delay between any two nodes
* \return Pointer to the created CsmaCdChannel
*
* Create a CsmaCdChannel. All nodes connected to a multipoint
* channels will receive all packets written to that channel
*/
static Ptr<CsmaCdChannel> CreateCsmaCdChannel(
const DataRate& dataRate, const Time& delay);
#if 0
/**
* \param n1 Node to be attached to the multipoint channel
* \param ch CsmaCdChannel to which node n1 should be attached
* \param addr MacAddress that should be assigned to the
* EthernetNetDevice that will be added to the node.
*
* Add a multipoint node to a multipoint channel
*/
static Ptr<CsmaCdNetDevice> AddCsmaCdEthernetNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr);
/**
* \param app Application that will be sending data to the agent
* \param ndSrc Net Device that will be sending the packets onto the
* network
* \param ndDest Net Device to which ndSrc will be sending the packets
* \return A pointer to the PacketSocket
*
* Creates an PacketSocket and configure it to send packets between
* two net devices
*/
static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
Ptr<CsmaCdNetDevice> ndDest);
/**
* \param app Application that will be sending data to the agent
* \param ndSrc Net Device that will be sending the packets onto the
* network
* \param macAddr Mac destination address for the packets send by
* the ndSrc net device \return a Pointer to the created
* PacketSocket
*
* Creates an PacketSocket and configure it to send packets from a
* net device to a destination MacAddress
*/
static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
MacAddress macAddr);
/**
* \param n1 Node from which socketfactory should be tested.
* \param iid_name Interface identifier ("Packet", in this case)
*
* This is a test function to make sure that a socket can be created
* by using the socketfactory interface provided in the
* netdevicenode.
*/
static Ptr<Socket> CreatePacketSocket(Ptr<Node> n1,
std::string iid_name);
#endif
};
} // namespace ns3
#endif

View File

@@ -0,0 +1,24 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
obj = bld.create_obj('cpp', 'shlib')
obj.name = 'ns3-csma-cd'
obj.target = obj.name
obj.uselib_local = ['ns3-node']
obj.source = [
'backoff.cc',
'csma-cd-net-device.cc',
'csma-cd-channel.cc',
'csma-cd-topology.cc',
'csma-cd-ipv4-topology.cc',
]
headers = bld.create_obj('ns3header')
headers.source = [
'backoff.h',
'csma-cd-net-device.h',
'csma-cd-channel.h',
'csma-cd-topology.h',
'csma-cd-ipv4-topology.h',
]

View File

@@ -1,22 +0,0 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
p2p = bld.create_obj('cpp', 'shlib')
p2p.name = 'ns3-p2p'
p2p.target = p2p.name
p2p.uselib_local = ['ns3-node']
p2p.source = [
'p2p-net-device.cc',
'p2p-channel.cc',
'p2p-topology.cc',
]
p2p.includes = '.'
headers = bld.create_obj('ns3header')
headers.source = [
'p2p-net-device.h',
'p2p-channel.h',
'p2p-topology.h',
]

View File

@@ -19,8 +19,8 @@
* Author: Craig Dowell <craigdo@ee.washington.edu>
*/
#include "p2p-channel.h"
#include "p2p-net-device.h"
#include "point-to-point-channel.h"
#include "point-to-point-net-device.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"
#include "ns3/debug.h"

View File

@@ -26,8 +26,9 @@
#include "ns3/queue.h"
#include "ns3/simulator.h"
#include "ns3/composite-trace-resolver.h"
#include "p2p-net-device.h"
#include "p2p-channel.h"
#include "point-to-point-net-device.h"
#include "point-to-point-channel.h"
#include "ns3/llc-snap-header.h"
NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice");
@@ -65,13 +66,30 @@ PointToPointNetDevice::~PointToPointNetDevice()
m_queue = 0;
}
void PointToPointNetDevice::AddHeader(Packet& p, const MacAddress& dest,
uint16_t protocolNumber)
{
LlcSnapHeader llc;
llc.SetType (protocolNumber);
p.AddHeader (llc);
}
bool PointToPointNetDevice::ProcessHeader(Packet& p, int& param)
{
LlcSnapHeader llc;
p.RemoveHeader (llc);
param = llc.GetType ();
return true;
}
void PointToPointNetDevice::DoDispose()
{
m_channel = 0;
NetDevice::DoDispose ();
}
void PointToPointNetDevice::SetDataRate(const DataRate& bps)
{
m_bps = bps;
@@ -82,7 +100,8 @@ void PointToPointNetDevice::SetInterframeGap(const Time& t)
m_tInterframeGap = t;
}
bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest,
uint16_t protocolNumber)
{
NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
@@ -91,6 +110,7 @@ bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest)
// "go down" during the simulation? Shouldn't we just wait for it
// to come back up?
NS_ASSERT (IsLinkUp ());
AddHeader(p, dest, protocolNumber);
//
// This class simulates a point to point device. In the case of a serial
@@ -198,9 +218,12 @@ void PointToPointNetDevice::AddQueue (Ptr<Queue> q)
void PointToPointNetDevice::Receive (Packet& p)
{
NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
int param = 0;
Packet packet = p;
m_rxTrace (p);
ForwardUp (p);
ProcessHeader(packet, param);
m_rxTrace (packet);
ForwardUp (packet, param);
}
Ptr<Queue> PointToPointNetDevice::GetQueue(void) const

View File

@@ -187,11 +187,18 @@ protected:
static const DataRate& GetDefaultRate();
private:
// unimplemented methods to make it impossible
// to copy these objects.
PointToPointNetDevice (const PointToPointNetDevice& nd);
PointToPointNetDevice& operator = (const PointToPointNetDevice&o);
/**
* Adds the necessary headers and trailers to a packet of data in order to
* respect the protocol implemented by the agent.
*/
void AddHeader(Packet& p, const MacAddress& dest, uint16_t protocolNumber);
/**
* Removes, from a packet of data, all headers and trailers that
* relate to the protocol implemented by the agent
* \return Returns true if the packet should be forwarded up the
* protocol stack.
*/
bool ProcessHeader(Packet& p, int& param);
/**
* Send a Packet Down the Wire.
*
@@ -202,9 +209,11 @@ private:
* @see NetDevice
* @param p a reference to the packet to send
* @param dest a reference to the MacAddress of the destination device
* @param protocolNumber Protocol Number used to find protocol touse
* @returns true if success, false on failure
*/
virtual bool SendTo (Packet& p, const MacAddress& dest);
virtual bool SendTo (Packet& p, const MacAddress& dest,
uint16_t protocolNumber);
/**
* Start Sending a Packet Down the Wire.
*

View File

@@ -32,9 +32,9 @@
#include "ns3/ipv4.h"
#include "ns3/queue.h"
#include "p2p-channel.h"
#include "p2p-net-device.h"
#include "p2p-topology.h"
#include "point-to-point-channel.h"
#include "point-to-point-net-device.h"
#include "point-to-point-topology.h"
namespace ns3 {

View File

@@ -0,0 +1,21 @@
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
def build(bld):
module = bld.create_obj('cpp', 'shlib')
module.name = 'ns3-point-to-point'
module.target = module.name
module.uselib_local = ['ns3-node']
module.source = [
'point-to-point-net-device.cc',
'point-to-point-channel.cc',
'point-to-point-topology.cc',
]
headers = bld.create_obj('ns3header')
headers.source = [
'point-to-point-net-device.h',
'point-to-point-channel.h',
'point-to-point-topology.h',
]
module.includes = '.'

View File

@@ -20,8 +20,8 @@
*/
#include "ns3/assert.h"
#include "ns3/address-utils.h"
#include "arp-header.h"
#include "header-utils.h"
namespace ns3 {

View File

@@ -24,7 +24,6 @@ def build(bld):
'arp-ipv4-interface.cc',
'arp-l3-protocol.cc',
'ipv4-loopback-interface.cc',
'header-utils.cc',
'udp-socket.cc',
'ipv4-end-point-demux.cc',
'arp-private.cc',

View File

@@ -18,7 +18,7 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "header-utils.h"
#include "address-utils.h"
namespace ns3 {

View File

@@ -18,8 +18,8 @@
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef HEADER_UTILS_H
#define HEADER_UTILS_H
#ifndef ADDRESS_UTILS_H
#define ADDRESS_UTILS_H
#include "ns3/buffer.h"
#include "ns3/ipv4-address.h"
@@ -35,4 +35,4 @@ void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len);
};
#endif /* HEADER_UTILS_H */
#endif /* ADDRESS_UTILS_H */

173
src/node/ethernet-header.cc Normal file
View File

@@ -0,0 +1,173 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include "ns3/assert.h"
#include "ns3/debug.h"
#include "ns3/header.h"
#include "ethernet-header.h"
#include "address-utils.h"
NS_DEBUG_COMPONENT_DEFINE ("EthernetHeader");
namespace ns3 {
bool EthernetHeader::m_enPreambleSfd = false;
EthernetHeader::EthernetHeader ()
{
Init();
}
EthernetHeader::~EthernetHeader ()
{}
void
EthernetHeader::Init()
{
m_preambleSfd = 0;
m_lengthType = 0x0;
}
void
EthernetHeader::EnablePreambleSfd (bool enable)
{
m_enPreambleSfd = enable;
}
void
EthernetHeader::SetLengthType (uint16_t lengthType)
{
m_lengthType = lengthType;
}
uint16_t
EthernetHeader::GetLengthType (void) const
{
return m_lengthType;
}
void
EthernetHeader::SetPreambleSfd (uint64_t preambleSfd)
{
m_preambleSfd = preambleSfd;
}
uint64_t
EthernetHeader::GetPreambleSfd (void) const
{
return m_preambleSfd;
}
void
EthernetHeader::SetSource (MacAddress source)
{
m_source = source;
}
MacAddress
EthernetHeader::GetSource (void) const
{
return m_source;
}
void
EthernetHeader::SetDestination (MacAddress dst)
{
m_destination = dst;
}
MacAddress
EthernetHeader::GetDestination (void) const
{
return m_destination;
}
ethernet_header_t
EthernetHeader::GetPacketType (void) const
{
return LENGTH;
}
uint32_t
EthernetHeader::GetHeaderSize (void) const
{
return GetSerializedSize();
}
std::string
EthernetHeader::DoGetName (void) const
{
return "ETHERNET";
}
void
EthernetHeader::PrintTo (std::ostream &os) const
{
// ethernet, right ?
os << "(ethernet)";
if (m_enPreambleSfd)
{
os << " preamble/sfd=" << m_preambleSfd << ",";
}
os << " length/type=" << m_lengthType
<< ", source=" << m_source
<< ", destination=" << m_destination;
}
uint32_t
EthernetHeader::GetSerializedSize (void) const
{
if (m_enPreambleSfd)
{
return PREAMBLE_SIZE + LENGTH_SIZE + 2*MAC_ADDR_SIZE;
} else {
return LENGTH_SIZE + 2*MAC_ADDR_SIZE;
}
}
void
EthernetHeader::SerializeTo (Buffer::Iterator start) const
{
Buffer::Iterator i = start;
if (m_enPreambleSfd)
{
i.WriteU64(m_preambleSfd);
}
NS_ASSERT (m_destination.GetLength () == MAC_ADDR_SIZE);
NS_ASSERT (m_source.GetLength () == MAC_ADDR_SIZE);
WriteTo (i, m_destination);
WriteTo (i, m_source);
i.WriteU16 (m_lengthType);
}
uint32_t
EthernetHeader::DeserializeFrom (Buffer::Iterator start)
{
Buffer::Iterator i = start;
if (m_enPreambleSfd)
{
m_enPreambleSfd = i.ReadU64 ();
}
ReadFrom (i, m_destination, MAC_ADDR_SIZE);
ReadFrom (i, m_source, MAC_ADDR_SIZE);
m_lengthType = i.ReadU16 ();
return GetSerializedSize ();
}
}; // namespace ns3

128
src/node/ethernet-header.h Normal file
View File

@@ -0,0 +1,128 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise
* All rights reserved.
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#ifndef ETHERNET_HEADER_H
#define ETHERNET_HEADER_H
#include "ns3/header.h"
#include "ns3/mac-address.h"
namespace ns3 {
/**
* Types of ethernet packets. Indicates the type of the current
* header.
*/
enum ethernet_header_t {
LENGTH, /**< Basic ethernet packet, no tags, type/length field
indicates packet length or IP/ARP packet */
VLAN, /**< Single tagged packet. Header includes VLAN tag */
QINQ /**< Double tagged packet. Header includes two VLAN tags */
};
/**
* \brief Packet header for Ethernet
*
* This class can be used to add a header to an ethernet packet that
* will specify the source and destination addresses and the length of
* the packet. Eventually the class will be improved to also support
* VLAN tags in packet headers.
*/
class EthernetHeader : public Header {
public:
static const int PREAMBLE_SIZE = 8; /// size of the preamble_sfd header field
static const int LENGTH_SIZE = 2; /// size of the length_type header field
static const int MAC_ADDR_SIZE = 6; /// size of src/dest addr header fields
/**
* \brief Construct a null ethernet header
*/
EthernetHeader ();
virtual ~EthernetHeader ();
/**
* \brief Enable or disabled the serialisation of the preamble and
* Sfd header fields
*/
static void EnablePreambleSfd (bool enable);
/**
* \param size The size of the payload in bytes
*/
void SetLengthType (uint16_t size);
/**
* \param source The source address of this packet
*/
void SetSource (MacAddress source);
/**
* \param destination The destination address of this packet.
*/
void SetDestination (MacAddress destination);
/**
* \param preambleSfd The value that the preambleSfd field should take
*/
void SetPreambleSfd (uint64_t preambleSfd);
/**
* \return The size of the payload in bytes
*/
uint16_t GetLengthType (void) const;
/**
* \return The type of packet (only basic Ethernet is currently supported)
*/
ethernet_header_t GetPacketType (void) const;
/**
* \return The source address of this packet
*/
MacAddress GetSource (void) const;
/**
* \return The destination address of this packet
*/
MacAddress GetDestination (void) const;
/**
* \return The value of the PreambleSfd field
*/
uint64_t GetPreambleSfd () const;
/**
* \return The size of the header
*/
uint32_t GetHeaderSize() const;
private:
virtual std::string DoGetName (void) const;
virtual void PrintTo (std::ostream &os) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void SerializeTo (Buffer::Iterator start) const;
virtual uint32_t DeserializeFrom (Buffer::Iterator start);
void Init (void);
/**
* If false, the preamble/sfd are not serialised/deserialised.
*/
static bool m_enPreambleSfd;
uint64_t m_preambleSfd; /// Value of the Preamble/SFD fields
uint16_t m_lengthType : 16; /// Length or type of the packet
MacAddress m_source; /// Source address
MacAddress m_destination; /// Destination address
};
}; // namespace ns3
#endif /* ETHERNET_HEADER_H */

View File

@@ -0,0 +1,124 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2005 INRIA
* All rights reserved.
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include "ns3/assert.h"
#include "ns3/debug.h"
#include "ns3/trailer.h"
#include "ethernet-trailer.h"
NS_DEBUG_COMPONENT_DEFINE ("EthernetTrailer");
namespace ns3 {
bool EthernetTrailer::m_calcFcs = false;
EthernetTrailer::EthernetTrailer ()
{
Init();
}
EthernetTrailer::~EthernetTrailer ()
{}
void EthernetTrailer::Init()
{
m_fcs = 0;
}
void
EthernetTrailer::EnableFcs (bool enable)
{
m_calcFcs = enable;
}
bool
EthernetTrailer::CheckFcs (const Packet& p) const
{
if (!m_calcFcs)
{
return true;
} else {
NS_DEBUG("FCS calculation is not yet enabled" << std::endl);
return false;
}
}
void
EthernetTrailer::CalcFcs (const Packet& p)
{
NS_DEBUG("FCS calculation is not yet enabled" << std::endl);
}
void
EthernetTrailer::SetFcs (uint32_t fcs)
{
m_fcs = fcs;
}
uint32_t
EthernetTrailer::GetFcs (void)
{
return m_fcs;
}
uint32_t
EthernetTrailer::GetTrailerSize (void) const
{
return GetSerializedSize();
}
std::string
EthernetTrailer::DoGetName (void) const
{
return "ETHERNET";
}
void
EthernetTrailer::PrintTo (std::ostream &os) const
{
os << " fcs=" << m_fcs;
}
uint32_t
EthernetTrailer::GetSerializedSize (void) const
{
return 4;
}
void
EthernetTrailer::SerializeTo (Buffer::Iterator end) const
{
Buffer::Iterator i = end;
i.Prev(GetSerializedSize());
i.WriteU32 (m_fcs);
}
uint32_t
EthernetTrailer::DeserializeFrom (Buffer::Iterator end)
{
Buffer::Iterator i = end;
uint32_t size = GetSerializedSize();
i.Prev(size);
m_fcs = i.ReadU32 ();
return size;
}
}; // namespace ns3

104
src/node/ethernet-trailer.h Normal file
View File

@@ -0,0 +1,104 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise
* All rights reserved.
*
* 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#ifndef ETHERNET_TRAILER_H
#define ETHERNET_TRAILER_H
#include "ns3/trailer.h"
#include "ns3/packet.h"
namespace ns3 {
/**
* \brief Packet trailer for Ethernet
*
* This class can be used to add and verify the FCS at the end of an
* ethernet packet. The actual FCS functionality is not yet coded and
* so this acts more as a placeholder.
*/
class EthernetTrailer : public Trailer {
public:
/**
* \brief Construct a null ethernet trailer
*/
EthernetTrailer ();
virtual ~EthernetTrailer ();
/**
* \brief Enable or disabled FCS checking and calculations
* \param enable If true, enables FCS calculations.
*/
static void EnableFcs (bool enable);
/**
* \brief Updates the Fcs Field to the correct FCS
* \param p Reference to a packet on which the FCS should be
* calculated. The packet should not currently contain an FCS
* trailer.
*/
void CalcFcs (const Packet& p);
/**
* \brief Sets the FCS to a new value
* \param fcs New FCS value
*/
void SetFcs (uint32_t fcs);
/**
* \return the FCS contained in this trailer
*/
uint32_t GetFcs ();
/**
* \param p Reference to the packet on which the FCS should be
* calculated. The packet should not contain an FCS trailer.
* \return Returns true if the packet fcs is correct, false otherwise.
*
* If FCS checking is disabled, this method will always
* return true.
*/
bool CheckFcs (const Packet& p) const;
/**
*\return Returns the size of the trailer
*/
uint32_t GetTrailerSize() const;
private:
virtual std::string DoGetName (void) const;
virtual void PrintTo (std::ostream &os) const;
virtual uint32_t GetSerializedSize (void) const;
virtual void SerializeTo (Buffer::Iterator end) const;
virtual uint32_t DeserializeFrom (Buffer::Iterator end);
/**
* Initializes the trailer parameters during construction.
*/
void Init (void);
/**
* Enabled FCS calculations. If false, fcs is set to 0 and checkFCS
* returns true.
*/
static bool m_calcFcs;
uint32_t m_fcs; /// Value of the fcs contained in the trailer
};
}; // namespace ns3
#endif /* ETHERNET_TRAILER_H */

View File

@@ -22,12 +22,15 @@
#include <iostream>
#include "ns3/assert.h"
#include "ns3/object.h"
#include "ns3/debug.h"
#include "channel.h"
#include "net-device.h"
#include "llc-snap-header.h"
#include "node.h"
NS_DEBUG_COMPONENT_DEFINE ("NetDevice");
namespace ns3 {
const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid);
@@ -172,10 +175,7 @@ NetDevice::Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber)
{
if (m_isUp)
{
LlcSnapHeader llc;
llc.SetType (protocolNumber);
p.AddHeader (llc);
return SendTo(p, dest);
return SendTo(p, dest, protocolNumber);
}
else
{
@@ -195,18 +195,24 @@ NetDevice::GetChannel (void) const
return DoGetChannel ();
}
// Receive packet from below
// Receive packets from below
bool
NetDevice::ForwardUp (Packet& packet)
NetDevice::ForwardUp(Packet& p, uint32_t param)
{
bool retval = false;
LlcSnapHeader llc;
packet.RemoveHeader (llc);
Packet packet = p;
NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid()
<< " device is: " << GetName());
if (!m_receiveCallback.IsNull ())
{
retval = m_receiveCallback (this, packet, llc.GetType ());
retval = m_receiveCallback (this, packet, param);
} else {
NS_DEBUG ("NetDevice::Receive call back is NULL");
}
return retval;
return retval;
}
void

View File

@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Modified by Emmanuelle Laprise to remove dependance on LLC headers
*/
#ifndef NET_DEVICE_H
#define NET_DEVICE_H
@@ -227,6 +228,8 @@ public:
/**
* \param p packet sent from below up to Network Device
* \param param Extra parameter extracted from header and needed by
* some protocols
* \returns true if the packet was forwarded successfully,
* false otherwise.
*
@@ -234,7 +237,8 @@ public:
* forwards it to the higher layers by calling this method
* which is responsible for passing it up to the Rx callback.
*/
bool ForwardUp (Packet& p);
bool ForwardUp (Packet& p, uint32_t param);
/**
* The dispose method for this NetDevice class.
@@ -244,10 +248,13 @@ public:
*/
virtual void DoDispose (void);
Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
private:
/**
* \param p packet to send
* \param dest address of destination to which packet must be sent
* \param protocolNumber Number of the protocol (used with some protocols)
* \returns true if the packet could be sent successfully, false
* otherwise.
*
@@ -255,7 +262,7 @@ public:
* method. When the link is Up, this method is invoked to ask
* subclasses to forward packets. Subclasses MUST override this method.
*/
virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
virtual bool SendTo (Packet& p, const MacAddress &dest, uint16_t protocolNumber) = 0;
/**
* \returns true if this NetDevice needs the higher-layers
* to perform ARP over it, false otherwise.
@@ -279,7 +286,7 @@ public:
*/
virtual Ptr<Channel> DoGetChannel (void) const = 0;
Ptr<Node> m_node;
Ptr<Node> m_node;
std::string m_name;
uint16_t m_ifIndex;
MacAddress m_address;
@@ -290,7 +297,6 @@ public:
bool m_isMulticast;
bool m_isPointToPoint;
Callback<void> m_linkChangeCallback;
Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
};
}; // namespace ns3

View File

@@ -10,7 +10,10 @@ def build(bld):
'ipv4-address.cc',
'net-device.cc',
'mac-address.cc',
'address-utils.cc',
'llc-snap-header.cc',
'ethernet-header.cc',
'ethernet-trailer.cc',
'ipv4-route.cc',
'queue.cc',
'drop-tail-queue.cc',
@@ -30,10 +33,13 @@ def build(bld):
'ipv4-address.h',
'net-device.h',
'mac-address.h',
'address-utils.h',
'ipv4-route.h',
'queue.h',
'drop-tail-queue.h',
'llc-snap-header.h',
'ethernet-header.h',
'ethernet-trailer.h',
'channel.h',
'node-list.h',
'socket.h',

View File

@@ -15,7 +15,8 @@ all_modules = (
'simulator',
'node',
'internet-node',
'devices/p2p',
'devices/point-to-point',
'devices/csma-cd',
'applications',
'mobility',
)