merge with trunk

This commit is contained in:
Mathieu Lacage
2007-08-06 17:21:57 +02:00
76 changed files with 2691 additions and 1411 deletions

View File

@@ -50,18 +50,14 @@
#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/eui48-address.h"
#include "ns3/ipv4-address.h"
#include "ns3/inet-socket-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;
@@ -105,13 +101,13 @@ int main (int argc, char *argv[])
DataRate(5000000), MilliSeconds(2));
uint32_t n0ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0,
MacAddress("10:54:23:54:23:50"));
Eui48Address("10:54:23:54:23:50"));
uint32_t n1ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
MacAddress("10:54:23:54:23:51"));
Eui48Address("10:54:23:54:23:51"));
uint32_t n2ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
MacAddress("10:54:23:54:23:52"));
Eui48Address("10:54:23:54:23:52"));
uint32_t n3ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
MacAddress("10:54:23:54:23:53"));
Eui48Address("10:54:23:54:23:53"));
// Later, we add IP addresses.
CsmaCdIpv4Topology::AddIpv4Address (
@@ -131,8 +127,7 @@ int main (int argc, char *argv[])
// from n0 to n1
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
n0,
Ipv4Address("10.1.1.2"),
80,
InetSocketAddress ("10.1.1.2", 80),
"Udp",
ConstantVariable(1),
ConstantVariable(0));
@@ -143,8 +138,7 @@ int main (int argc, char *argv[])
// Create a similar flow from n3 to n0, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
Ipv4Address("10.1.1.1"),
80,
InetSocketAddress ("10.1.1.1", 80),
"Udp",
ConstantVariable(1),
ConstantVariable(0));

View File

@@ -0,0 +1,136 @@
/* -*- 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 n1 n2 n3
// | | | |
// =====================
//
// - 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 "csma-cd-one-subnet.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/eui48-address.h"
#include "ns3/packet-socket-address.h"
#include "ns3/socket.h"
#include "ns3/onoff-application.h"
#include "ns3/queue.h"
using namespace ns3;
static Ptr<CsmaCdNetDevice>
CreateCsmaCdDevice (Ptr<Node> node, Ptr<CsmaCdChannel> channel)
{
Ptr<CsmaCdNetDevice> device = Create<CsmaCdNetDevice> (node);
device->Attach (channel);
Ptr<Queue> queue = Queue::CreateDefault ();
device->AddQueue (queue);
return device;
}
int main (int argc, char *argv[])
{
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<Node> ();
Ptr<Node> n1 = Create<Node> ();
Ptr<Node> n2 = Create<Node> ();
Ptr<Node> n3 = Create<Node> ();
// create the shared medium used by all csma/cd devices.
Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (DataRate(5000000), MilliSeconds(2));
// use a helper function to connect our nodes to the shared channel.
Ptr<NetDevice> n0If = CreateCsmaCdDevice (n0, channel);
Ptr<NetDevice> n1If = CreateCsmaCdDevice (n1, channel);
Ptr<NetDevice> n2If = CreateCsmaCdDevice (n2, channel);
Ptr<NetDevice> n3If = CreateCsmaCdDevice (n3, channel);
// create the address which identifies n1 from n0
PacketSocketAddress n0ToN1;
n0ToN1.SetSingleDevice (n0If->GetIfIndex ()); // set outgoing interface for outgoing packets
n0ToN1.SetPhysicalAddress (n1If->GetAddress ()); // set destination address for outgoing packets
n0ToN1.SetProtocol (2); // set arbitrary protocol for outgoing packets
// create the address which identifies n0 from n3
PacketSocketAddress n3ToN0;
n3ToN0.SetSingleDevice (n3If->GetIfIndex ());
n3ToN0.SetPhysicalAddress (n0If->GetAddress ());
n3ToN0.SetProtocol (3);
// Create the OnOff application to send raw datagrams of size
// 210 bytes at a rate of 448 Kb/s
// from n0 to n1
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
n0,
n0ToN1,
"Packet",
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,
n3ToN0,
"Packet",
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 csma-cd-packet-socket.tr file
AsciiTrace asciitrace ("csma-cd-packet-socket.tr");
asciitrace.TraceAllNetDeviceRx ();
asciitrace.TraceAllQueues ();
Simulator::Run ();
Simulator::Destroy ();
}

View File

@@ -58,10 +58,10 @@
#include "ns3/internet-node.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/inet-socket-address.h"
#include "ns3/ipv4-route.h"
#include "ns3/point-to-point-topology.h"
#include "ns3/onoff-application.h"
@@ -82,7 +82,7 @@ int main (int argc, char *argv[])
DebugComponentEnable ("PointToPointChannel");
DebugComponentEnable ("PointToPointNetDevice");
DebugComponentEnable ("GlobalRouter");
DebugComponentEnable ("GlobalRouteManager");
DebugComponentEnable ("GlobalRouteMaager");
#endif
// Set up some default values for the simulation. Use the Bind ()
@@ -143,8 +143,7 @@ int main (int argc, char *argv[])
// 210 bytes at a rate of 448 Kb/s
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
n0,
Ipv4Address ("10.1.3.2"),
80,
InetSocketAddress ("10.1.3.2", 80),
"Udp",
ConstantVariable (1),
ConstantVariable (0));
@@ -155,8 +154,7 @@ int main (int argc, char *argv[])
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
Ipv4Address ("10.1.2.1"),
80,
InetSocketAddress ("10.1.2.1", 80),
"Udp",
ConstantVariable (1),
ConstantVariable (0));
@@ -180,4 +178,6 @@ int main (int argc, char *argv[])
Simulator::Run ();
Simulator::Destroy ();
return 0;
}

View File

@@ -56,8 +56,8 @@
#include "ns3/internet-node.h"
#include "ns3/p2p-channel.h"
#include "ns3/p2p-net-device.h"
#include "ns3/mac-address.h"
#include "ns3/ipv4-address.h"
#include "ns3/inet-socket-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
@@ -143,8 +143,7 @@ int main (int argc, char *argv[])
// 210 bytes at a rate of 448 Kb/s
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
n0,
Ipv4Address("10.1.3.2"),
80,
InetSocketAddress("10.1.3.2", 80).ConvertTo (),
"Udp",
ConstantVariable(1),
ConstantVariable(0));
@@ -155,8 +154,7 @@ int main (int argc, char *argv[])
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
Ipv4Address("10.1.2.1"),
80,
InetSocketAddress("10.1.2.1", 80).ConvertTo (),
"Udp",
ConstantVariable(1),
ConstantVariable(0));

View File

@@ -57,8 +57,8 @@
#include "ns3/internet-node.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/inet-socket-address.h"
#include "ns3/ipv4.h"
#include "ns3/socket.h"
#include "ns3/ipv4-route.h"
@@ -144,8 +144,7 @@ int main (int argc, char *argv[])
// 210 bytes at a rate of 448 Kb/s
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
n0,
Ipv4Address("10.1.3.2"),
80,
InetSocketAddress ("10.1.3.2", 80),
"Udp",
ConstantVariable(1),
ConstantVariable(0));
@@ -156,8 +155,7 @@ int main (int argc, char *argv[])
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
ooff = Create<OnOffApplication> (
n3,
Ipv4Address("10.1.2.1"),
80,
InetSocketAddress ("10.1.2.1", 80),
"Udp",
ConstantVariable(1),
ConstantVariable(0));

View File

@@ -15,4 +15,5 @@ def build(bld):
deps=['point-to-point', 'internet-node'])
obj = create_ns_prog('csma-cd-one-subnet', 'csma-cd-one-subnet.cc',
deps=['csma-cd', 'internet-node'])
obj = create_ns_prog('csma-cd-packet-socket', 'csma-cd-packet-socket.cc', deps=['csma-cd', 'internet-node'])

View File

@@ -4,6 +4,7 @@
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
#include "ns3/socket.h"
#include "ns3/inet-socket-address.h"
#include "ns3/nstime.h"
using namespace ns3;
@@ -24,7 +25,7 @@ GenerateTraffic (Ptr<Socket> socket, uint32_t size)
}
static void
SocketPrinter (Ptr<Socket> socket, uint32_t size, const Ipv4Address &from, uint16_t fromPort)
SocketPrinter (Ptr<Socket> socket, uint32_t size, const Address &from)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
}
@@ -44,10 +45,12 @@ RunSimulation (void)
Ptr<SocketFactory> socketFactory = a->QueryInterface<SocketFactory> (iid);
Ptr<Socket> sink = socketFactory->CreateSocket ();
sink->Bind (80);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
sink->Bind (local);
Ptr<Socket> source = socketFactory->CreateSocket ();
source->Connect (Ipv4Address::GetLoopback (), 80);
InetSocketAddress remote = InetSocketAddress (Ipv4Address::GetLoopback (), 80);
source->Connect (remote);
GenerateTraffic (source, 500);
PrintTraffic (sink);

View File

@@ -22,7 +22,7 @@
// George F. Riley, Georgia Tech, Spring 2007
// Adapted from ApplicationOnOff in GTNetS.
#include "ns3/ipv4-address.h"
#include "ns3/address.h"
#include "ns3/node.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
@@ -47,22 +47,20 @@ static NumericDefaultValue<uint32_t> g_defaultSize ("OnOffApplicationPacketSize"
// Constructors
OnOffApplication::OnOffApplication(Ptr<Node> n,
const Ipv4Address rip,
uint16_t rport,
const Address &remote,
std::string iid,
const RandomVariable& ontime,
const RandomVariable& offtime)
: Application(n),
m_cbrRate (g_defaultRate.GetValue ())
{
Construct (n, rip, rport, iid,
Construct (n, remote, iid,
ontime, offtime,
g_defaultSize.GetValue ());
}
OnOffApplication::OnOffApplication(Ptr<Node> n,
const Ipv4Address rip,
uint16_t rport,
const Address &remote,
std::string iid,
const RandomVariable& ontime,
const RandomVariable& offtime,
@@ -71,22 +69,20 @@ OnOffApplication::OnOffApplication(Ptr<Node> n,
: Application(n),
m_cbrRate (rate)
{
Construct (n, rip, rport, iid,
Construct (n, remote, iid,
ontime, offtime, size);
}
void
OnOffApplication::Construct (Ptr<Node> n,
const Ipv4Address rip,
uint16_t rport,
const Address &remote,
std::string iid,
const RandomVariable& onTime,
const RandomVariable& offTime,
uint32_t size)
{
m_socket = 0;
m_peerIp = rip;
m_peerPort = rport;
m_peer = remote;
m_connected = false;
m_onTime = onTime.Copy ();
m_offTime = offTime.Copy ();
@@ -144,7 +140,7 @@ void OnOffApplication::StartApplication() // Called at time specified by Star
Ptr<SocketFactory> socketFactory = GetNode ()->QueryInterface<SocketFactory> (iid);
m_socket = socketFactory->CreateSocket ();
m_socket->Bind ();
m_socket->Connect (m_peerIp, m_peerPort);
m_socket->Connect (m_peer);
}
// Insure no pending event
StopApplication();

View File

@@ -31,7 +31,7 @@
namespace ns3 {
class Ipv4Address;
class Address;
class RandomVariable;
class Socket;
class DataRate;
@@ -52,23 +52,20 @@ class OnOffApplication : public Application
public:
/**
* \param n node associated to this application
* \param rip remote ip address
* \param rport remove port number
* \param remote remote ip address
* \param iid
* \param ontime on time random variable
* \param offtime off time random variable
*/
OnOffApplication(Ptr<Node> n,
const Ipv4Address rip,
uint16_t rport,
const Address &remote,
std::string iid,
const RandomVariable& ontime,
const RandomVariable& offtime);
/**
* \param n node associated to this application
* \param rip remote ip address
* \param rport remove port number
* \param remote remote ip address
* \param iid
* \param ontime on time random variable
* \param offtime off time random variable
@@ -76,8 +73,7 @@ public:
* \param size size of packets when sending data.
*/
OnOffApplication(Ptr<Node> n,
const Ipv4Address rip,
uint16_t rport,
const Address &remote,
std::string iid,
const RandomVariable& ontime,
const RandomVariable& offtime,
@@ -112,8 +108,7 @@ private:
virtual void StopApplication (void); // Called at time specified by Stop
void Construct (Ptr<Node> n,
const Ipv4Address rip,
uint16_t rport,
const Address &remote,
std::string iid,
const RandomVariable& ontime,
const RandomVariable& offtime,
@@ -126,8 +121,7 @@ private:
void SendPacket();
Ptr<Socket> m_socket; // Associated socket
Ipv4Address m_peerIp; // Peer IP address
uint16_t m_peerPort; // Peer port
Address m_peer; // Peer address
bool m_connected; // True if connected
RandomVariable* m_onTime; // rng for On Time
RandomVariable* m_offTime; // rng for Off Time

View File

@@ -53,11 +53,11 @@ public:
*/
ArrayTraceResolver (TraceContext const &context,
Callback<uint32_t> getSize,
Callback<T *, uint32_t> get);
Callback<T, uint32_t> get);
private:
virtual TraceResolverList DoLookup (std::string id) const;
Callback<uint32_t> m_getSize;
Callback<T *, uint32_t> m_get;
Callback<T, uint32_t> m_get;
};
}//namespace ns3
@@ -66,7 +66,7 @@ namespace ns3 {
template <typename T, typename INDEX>
ArrayTraceResolver<T,INDEX>::ArrayTraceResolver (TraceContext const &context,
Callback<uint32_t> getSize,
Callback<T *, uint32_t> get)
Callback<T, uint32_t> get)
: TraceResolver (context),
m_getSize (getSize),
m_get (get)

View File

@@ -31,7 +31,7 @@ namespace ns3 {
#ifdef HAVE_SIGNAL_H
void
Breakpoint (void)
BreakpointFallback (void)
{
raise (SIGTRAP);
}
@@ -39,7 +39,7 @@ Breakpoint (void)
#else
void
Breakpoint (void)
BreakpointFallback (void)
{
int *a = 0;
/**

View File

@@ -38,7 +38,7 @@ namespace ns3 {
uint32_t
CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr)
Eui48Address addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
@@ -55,7 +55,7 @@ CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
void
CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr)
Eui48Address addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
@@ -75,7 +75,7 @@ CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
void
CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr)
Eui48Address addr)
{
Ptr<Queue> q = Queue::CreateDefault ();

View File

@@ -62,8 +62,8 @@ public:
* \return ifIndex of the device
*/
static uint32_t AddIpv4CsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr);
Ptr<CsmaCdChannel> ch,
Eui48Address addr);
/**
* \param n1 Node to be attached to the Csma/Cd channel
@@ -76,7 +76,7 @@ public:
*/
static void AddIpv4RawCsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr);
Eui48Address addr);
/**
* \param n1 Node to be attached to the Csma/Cd channel
@@ -89,7 +89,7 @@ public:
*/
static void AddIpv4LlcCsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
MacAddress addr);
Eui48Address addr);

View File

@@ -35,9 +35,19 @@ NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice");
namespace ns3 {
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node)
: NetDevice (node, Eui48Address::Allocate ()),
m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
m_encapMode = IP_ARP;
Init(true, true);
}
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaCdEncapsulationMode encapMode)
: NetDevice(node, addr), m_bps (DataRate (0xffffffff))
: NetDevice(node, addr),
m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
m_encapMode = encapMode;
@@ -45,10 +55,11 @@ CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
Init(true, true);
}
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, MacAddress addr,
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaCdEncapsulationMode encapMode,
bool sendEnable, bool receiveEnable)
: NetDevice(node, addr), m_bps (DataRate (0xffffffff))
: NetDevice(node, addr),
m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
m_encapMode = encapMode;
@@ -94,7 +105,7 @@ CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
m_channel = 0;
m_queue = 0;
EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
EnableMulticast();
EnablePointToPoint();
@@ -149,7 +160,7 @@ CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
m_backoff.m_maxRetries = maxRetries;
}
void
CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest,
CsmaCdNetDevice::AddHeader (Packet& p, Eui48Address dest,
uint16_t protocolNumber)
{
if (m_encapMode == RAW)
@@ -158,7 +169,8 @@ CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest,
}
EthernetHeader header (false);
EthernetTrailer trailer;
header.SetSource(this->GetAddress());
Eui48Address source = Eui48Address::ConvertFrom (GetAddress ());
header.SetSource(source);
header.SetDestination(dest);
uint16_t lengthType = 0;
@@ -198,8 +210,8 @@ CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param)
trailer.CheckFcs(p);
p.RemoveHeader(header);
if ((header.GetDestination() != this->GetBroadcast()) &&
(header.GetDestination() != this->GetAddress()))
if ((header.GetDestination() != GetBroadcast ()) &&
(header.GetDestination() != GetAddress ()))
{
return false;
}
@@ -236,7 +248,7 @@ CsmaCdNetDevice::DoNeedsArp (void) const
}
bool
CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber)
CsmaCdNetDevice::SendTo (Packet& p, const Address& dest, uint16_t protocolNumber)
{
NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
@@ -247,7 +259,8 @@ CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNum
if (!IsSendEnabled())
return false;
AddHeader(p, dest, protocolNumber);
Eui48Address destination = Eui48Address::ConvertFrom (dest);
AddHeader(p, destination, protocolNumber);
// Place the packet to be sent on the send queue
if (m_queue->Enqueue(p) == false )
@@ -451,26 +464,62 @@ CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
}
void
CsmaCdNetDevice::Receive (Packet& p)
CsmaCdNetDevice::Receive (const Packet& packet)
{
EthernetHeader header (false);
EthernetTrailer trailer;
Eui48Address broadcast;
Eui48Address destination;
Packet p = packet;
NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
// Only receive if send side of net device is enabled
if (!IsReceiveEnabled())
return;
uint16_t param = 0;
Packet packet = p;
if (ProcessHeader(packet, param))
{
m_rxTrace (packet);
ForwardUp (packet, param);
}
else
{
m_dropTrace (packet);
goto drop;
}
if (m_encapMode == RAW)
{
ForwardUp (packet, 0, GetBroadcast ());
goto drop;
}
p.RemoveTrailer(trailer);
trailer.CheckFcs(p);
p.RemoveHeader(header);
broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
destination = Eui48Address::ConvertFrom (GetAddress ());
if ((header.GetDestination() != broadcast) &&
(header.GetDestination() != destination))
{
// not for us.
goto drop;
}
uint16_t protocol;
switch (m_encapMode)
{
case ETHERNET_V1:
case IP_ARP:
protocol = header.GetLengthType();
break;
case LLC: {
LlcSnapHeader llc;
p.RemoveHeader (llc);
protocol = llc.GetType ();
} break;
case RAW:
NS_ASSERT (false);
break;
}
m_rxTrace (p);
ForwardUp (p, protocol, header.GetSource ());
return;
drop:
m_dropTrace (p);
}
Ptr<Queue>

View File

@@ -25,7 +25,7 @@
#include <string.h>
#include "ns3/node.h"
#include "ns3/backoff.h"
#include "ns3/mac-address.h"
#include "ns3/address.h"
#include "ns3/net-device.h"
#include "ns3/callback.h"
#include "ns3/packet.h"
@@ -34,6 +34,7 @@
#include "ns3/data-rate.h"
#include "ns3/ptr.h"
#include "ns3/random-variable.h"
#include "ns3/eui48-address.h"
namespace ns3 {
@@ -82,6 +83,7 @@ enum CsmaCdEncapsulationMode {
LLC, /**< LLC packet encapsulation */
};
CsmaCdNetDevice (Ptr<Node> node);
/**
* Construct a CsmaCdNetDevice
*
@@ -92,8 +94,8 @@ enum CsmaCdEncapsulationMode {
* \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,
CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr, CsmaCdEncapsulationMode pktType);
CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaCdEncapsulationMode pktType,
bool sendEnable, bool receiveEnable);
/**
@@ -172,7 +174,7 @@ enum CsmaCdEncapsulationMode {
* @see CsmaCdChannel
* \param p a reference to the received packet
*/
void Receive (Packet& p);
void Receive (const Packet& p);
bool IsSendEnabled (void);
bool IsReceiveEnabled (void);
@@ -210,7 +212,7 @@ protected:
* \param protocolNumber In some protocols, identifies the type of
* payload contained in this packet.
*/
void AddHeader (Packet& p, const MacAddress& dest,
void AddHeader (Packet& p, Eui48Address dest,
uint16_t protocolNumber);
/**
* Removes, from a packet of data, all headers and trailers that
@@ -247,7 +249,7 @@ private:
* \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);
virtual bool SendTo (Packet& p, const Address& dest, uint16_t protocolNumber);
/**
* Start Sending a Packet Down the Wire.

View File

@@ -24,12 +24,7 @@
#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

View File

@@ -26,9 +26,10 @@
#include "ns3/queue.h"
#include "ns3/simulator.h"
#include "ns3/composite-trace-resolver.h"
#include "ns3/eui48-address.h"
#include "ns3/llc-snap-header.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");
@@ -39,10 +40,10 @@ DataRateDefaultValue PointToPointNetDevice::g_defaultRate(
"The default data rate for point to point links",
DataRate ("10Mb/s"));
PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
const DataRate& rate)
PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
const DataRate& rate)
:
NetDevice(node, MacAddress (6)),
NetDevice(node, Eui48Address::Allocate ()),
m_txMachineState (READY),
m_bps (rate),
m_tInterframeGap (Seconds(0)),
@@ -55,7 +56,7 @@ DataRateDefaultValue PointToPointNetDevice::g_defaultRate(
// BUGBUG FIXME
//
// You _must_ support broadcast to get any sort of packet from the ARP layer.
EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff"));
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
EnableMulticast();
EnablePointToPoint();
}
@@ -66,15 +67,16 @@ PointToPointNetDevice::~PointToPointNetDevice()
m_queue = 0;
}
void PointToPointNetDevice::AddHeader(Packet& p, const MacAddress& dest,
uint16_t protocolNumber)
void
PointToPointNetDevice::AddHeader(Packet& p, uint16_t protocolNumber)
{
LlcSnapHeader llc;
llc.SetType (protocolNumber);
p.AddHeader (llc);
}
bool PointToPointNetDevice::ProcessHeader(Packet& p, uint16_t& param)
bool
PointToPointNetDevice::ProcessHeader(Packet& p, uint16_t& param)
{
LlcSnapHeader llc;
p.RemoveHeader (llc);
@@ -100,7 +102,7 @@ void PointToPointNetDevice::SetInterframeGap(const Time& t)
m_tInterframeGap = t;
}
bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest,
bool PointToPointNetDevice::SendTo (Packet& p, const Address& dest,
uint16_t protocolNumber)
{
NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
@@ -110,7 +112,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);
AddHeader(p, protocolNumber);
//
// This class simulates a point to point device. In the case of a serial
@@ -119,14 +121,14 @@ bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest,
//
// If there's a transmission in progress, we enque the packet for later
// trnsmission; otherwise we send it now.
if (m_txMachineState == READY)
{
return TransmitStart (p);
}
else
{
return m_queue->Enqueue(p);
}
if (m_txMachineState == READY)
{
return TransmitStart (p);
}
else
{
return m_queue->Enqueue(p);
}
}
bool
@@ -218,12 +220,12 @@ void PointToPointNetDevice::AddQueue (Ptr<Queue> q)
void PointToPointNetDevice::Receive (Packet& p)
{
NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
uint16_t param = 0;
uint16_t protocol = 0;
Packet packet = p;
ProcessHeader(packet, param);
ProcessHeader(packet, protocol);
m_rxTrace (packet);
ForwardUp (packet, param);
ForwardUp (packet, protocol, GetBroadcast ());
}
Ptr<Queue> PointToPointNetDevice::GetQueue(void) const

View File

@@ -22,7 +22,7 @@
#define POINT_TO_POINT_NET_DEVICE_H
#include <string.h>
#include "ns3/mac-address.h"
#include "ns3/address.h"
#include "ns3/node.h"
#include "ns3/net-device.h"
#include "ns3/callback.h"
@@ -191,7 +191,7 @@ private:
* 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);
void AddHeader(Packet& p, uint16_t protocolNumber);
/**
* Removes, from a packet of data, all headers and trailers that
* relate to the protocol implemented by the agent
@@ -208,11 +208,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 dest a reference to the Address 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 Address& dest,
uint16_t protocolNumber);
/**
* Start Sending a Packet Down the Wire.

View File

@@ -148,7 +148,7 @@ ArpCache::Entry::MarkDead (void)
UpdateSeen ();
}
Packet
ArpCache::Entry::MarkAlive (MacAddress macAddress)
ArpCache::Entry::MarkAlive (Address macAddress)
{
NS_ASSERT (m_state == WAIT_REPLY);
//NS_ASSERT (m_waiting != 0);
@@ -182,7 +182,7 @@ ArpCache::Entry::MarkWaitReply (Packet waiting)
UpdateSeen ();
}
MacAddress
Address
ArpCache::Entry::GetMacAddress (void)
{
NS_ASSERT (m_state == ALIVE);

View File

@@ -26,7 +26,7 @@
#include "ns3/nstime.h"
#include "ns3/net-device.h"
#include "ns3/ipv4-address.h"
#include "ns3/mac-address.h"
#include "ns3/address.h"
#include "ns3/ptr.h"
#include "sgi-hashmap.h"
@@ -101,7 +101,7 @@ public:
* \param macAddress
* \return
*/
Packet MarkAlive (MacAddress macAddress);
Packet MarkAlive (Address macAddress);
/**
* \param waiting
*/
@@ -127,7 +127,7 @@ public:
/**
* \return The MacAddress of this entry
*/
MacAddress GetMacAddress (void);
Address GetMacAddress (void);
/**
* \return True if this entry has timedout; false otherwise.
*/
@@ -143,7 +143,7 @@ public:
ArpCache *m_arp;
ArpCacheEntryState_e m_state;
Time m_lastSeen;
MacAddress m_macAddress;
Address m_macAddress;
Packet m_waiting;
};

View File

@@ -38,9 +38,9 @@ ArpHeader::~ArpHeader ()
{}
void
ArpHeader::SetRequest (MacAddress sourceHardwareAddress,
ArpHeader::SetRequest (Address sourceHardwareAddress,
Ipv4Address sourceProtocolAddress,
MacAddress destinationHardwareAddress,
Address destinationHardwareAddress,
Ipv4Address destinationProtocolAddress)
{
m_type = ARP_TYPE_REQUEST;
@@ -50,9 +50,9 @@ ArpHeader::SetRequest (MacAddress sourceHardwareAddress,
m_ipv4Dest = destinationProtocolAddress;
}
void
ArpHeader::SetReply (MacAddress sourceHardwareAddress,
ArpHeader::SetReply (Address sourceHardwareAddress,
Ipv4Address sourceProtocolAddress,
MacAddress destinationHardwareAddress,
Address destinationHardwareAddress,
Ipv4Address destinationProtocolAddress)
{
m_type = ARP_TYPE_REPLY;
@@ -71,12 +71,12 @@ ArpHeader::IsReply (void) const
{
return (m_type == ARP_TYPE_REPLY)?true:false;
}
MacAddress
Address
ArpHeader::GetSourceHardwareAddress (void)
{
return m_macSource;
}
MacAddress
Address
ArpHeader::GetDestinationHardwareAddress (void)
{
return m_macDest;

View File

@@ -23,7 +23,7 @@
#define ARP_HEADER_H
#include "ns3/header.h"
#include "ns3/mac-address.h"
#include "ns3/address.h"
#include "ns3/ipv4-address.h"
#include <string>
@@ -38,18 +38,18 @@ public:
virtual ~ArpHeader ();
void SetRequest (MacAddress sourceHardwareAddress,
void SetRequest (Address sourceHardwareAddress,
Ipv4Address sourceProtocolAddress,
MacAddress destinationHardwareAddress,
Address destinationHardwareAddress,
Ipv4Address destinationProtocolAddress);
void SetReply (MacAddress sourceHardwareAddress,
void SetReply (Address sourceHardwareAddress,
Ipv4Address sourceProtocolAddress,
MacAddress destinationHardwareAddress,
Address destinationHardwareAddress,
Ipv4Address destinationProtocolAddress);
bool IsRequest (void) const;
bool IsReply (void) const;
MacAddress GetSourceHardwareAddress (void);
MacAddress GetDestinationHardwareAddress (void);
Address GetSourceHardwareAddress (void);
Address GetDestinationHardwareAddress (void);
Ipv4Address GetSourceIpv4Address (void);
Ipv4Address GetDestinationIpv4Address (void);
@@ -78,8 +78,8 @@ private:
ARP_TYPE_REPLY = 2
};
uint16_t m_type;
MacAddress m_macSource;
MacAddress m_macDest;
Address m_macSource;
Address m_macDest;
Ipv4Address m_ipv4Source;
Ipv4Address m_ipv4Dest;
};

View File

@@ -25,10 +25,11 @@
#include "ns3/composite-trace-resolver.h"
#include "ns3/node.h"
#include "ns3/net-device.h"
#include "ns3/address.h"
#include "arp-ipv4-interface.h"
#include "arp-private.h"
#include "ipv4-l3-protocol.h"
#include "arp-l3-protocol.h"
namespace ns3 {
@@ -59,18 +60,17 @@ ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
NS_ASSERT (GetDevice () != 0);
if (GetDevice ()->NeedsArp ())
{
Ptr<ArpPrivate> arp = m_node->QueryInterface<ArpPrivate> (ArpPrivate::iid);
MacAddress hardwareDestination;
Ptr<ArpL3Protocol> arp = m_node->QueryInterface<ArpL3Protocol> (ArpL3Protocol::iid);
Address hardwareDestination;
bool found;
if (dest.IsBroadcast ())
{
hardwareDestination = GetDevice ()->GetBroadcast ();
found = true;
hardwareDestination = GetDevice ()->GetBroadcast ();
found = true;
}
else
{
Ptr<ArpPrivate> arp = m_node->QueryInterface<ArpPrivate> (ArpPrivate::iid);
found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
}

View File

@@ -24,22 +24,24 @@
#include "ns3/node.h"
#include "ns3/net-device.h"
#include "ipv4-l3-protocol.h"
#include "arp-l3-protocol.h"
#include "arp-header.h"
#include "arp-cache.h"
#include "ipv4-interface.h"
#include "ipv4-private.h"
NS_DEBUG_COMPONENT_DEFINE ("ArpL3Protocol");
namespace ns3 {
const InterfaceId ArpL3Protocol::iid = MakeInterfaceId ("ArpL3Protocol", Object::iid);
const uint16_t ArpL3Protocol::PROT_NUMBER = 0x0806;
ArpL3Protocol::ArpL3Protocol (Ptr<Node> node)
: L3Protocol (PROT_NUMBER, 0/* XXX: correct version number ? */ ),
m_node (node)
{}
: m_node (node)
{
SetInterfaceId (ArpL3Protocol::iid);
}
ArpL3Protocol::~ArpL3Protocol ()
{}
@@ -53,7 +55,7 @@ ArpL3Protocol::DoDispose (void)
}
m_cacheList.clear ();
m_node = 0;
L3Protocol::DoDispose ();
Object::DoDispose ();
}
TraceResolver *
@@ -72,7 +74,7 @@ ArpL3Protocol::FindCache (Ptr<NetDevice> device)
return *i;
}
}
Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
Ipv4Interface *interface = ipv4->FindInterfaceForDevice (device);
ArpCache * cache = new ArpCache (device, interface);
NS_ASSERT (device->IsBroadcast ());
@@ -82,10 +84,11 @@ ArpL3Protocol::FindCache (Ptr<NetDevice> device)
}
void
ArpL3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
ArpL3Protocol::Receive(Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from)
{
ArpCache *cache = FindCache (device);
ArpHeader arp;
Packet packet = p;
packet.RemoveHeader (arp);
NS_DEBUG ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
@@ -104,7 +107,7 @@ ArpL3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
}
else if (arp.IsReply () &&
arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress ()) &&
arp.GetDestinationHardwareAddress ().IsEqual (device->GetAddress ()))
arp.GetDestinationHardwareAddress () == device->GetAddress ())
{
Ipv4Address from = arp.GetSourceIpv4Address ();
ArpCache::Entry *entry = cache->Lookup (from);
@@ -115,7 +118,7 @@ ArpL3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
NS_DEBUG ("node="<<m_node->GetId ()<<", got reply from " <<
arp.GetSourceIpv4Address ()
<< " for waiting entry -- flush");
MacAddress from_mac = arp.GetSourceHardwareAddress ();
Address from_mac = arp.GetSourceHardwareAddress ();
Packet waiting = entry->MarkAlive (from_mac);
cache->GetInterface ()->Send (waiting, arp.GetSourceIpv4Address ());
}
@@ -144,8 +147,8 @@ ArpL3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
}
bool
ArpL3Protocol::Lookup (Packet &packet, Ipv4Address destination,
Ptr<NetDevice> device,
MacAddress *hardwareDestination)
Ptr<NetDevice> device,
Address *hardwareDestination)
{
ArpCache *cache = FindCache (device);
ArpCache::Entry *entry = cache->Lookup (destination);
@@ -231,7 +234,7 @@ ArpL3Protocol::SendArpRequest (ArpCache const *cache, Ipv4Address to)
}
void
ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac)
ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, Address toMac)
{
ArpHeader arp;
NS_DEBUG ("ARP: sending reply from node "<<m_node->GetId ()<<

View File

@@ -23,9 +23,8 @@
#include <list>
#include "ns3/ipv4-address.h"
#include "ns3/mac-address.h"
#include "ns3/address.h"
#include "ns3/ptr.h"
#include "l3-protocol.h"
namespace ns3 {
@@ -38,22 +37,23 @@ class TraceContext;
/**
* \brief An implementation of the ARP protocol
*/
class ArpL3Protocol : public L3Protocol
class ArpL3Protocol : public Object
{
public:
static const InterfaceId iid;
static const uint16_t PROT_NUMBER;
/**
* \brief Constructor
* \param node The node which this ARP object is associated with
*/
ArpL3Protocol (Ptr<Node> node);
~ArpL3Protocol ();
virtual ~ArpL3Protocol ();
virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
/**
* \brief Recieve a packet
*/
virtual void Receive(Packet& p, Ptr<NetDevice> device);
void Receive(Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from);
/**
* \brief Perform an ARP lookup
* \param p
@@ -64,14 +64,14 @@ public:
*/
bool Lookup (Packet &p, Ipv4Address destination,
Ptr<NetDevice> device,
MacAddress *hardwareDestination);
Address *hardwareDestination);
protected:
virtual void DoDispose (void);
private:
typedef std::list<ArpCache *> CacheList;
ArpCache *FindCache (Ptr<NetDevice> device);
void SendArpRequest (ArpCache const *cache, Ipv4Address to);
void SendArpReply (ArpCache const *cache, Ipv4Address toIp, MacAddress toMac);
void SendArpReply (ArpCache const *cache, Ipv4Address toIp, Address toMac);
CacheList m_cacheList;
Ptr<Node> m_node;
};

View File

@@ -26,12 +26,6 @@
#include "ns3/node.h"
#include "ns3/queue.h"
#include "ns3/node-list.h"
#include "ns3/llc-snap-header.h"
#include "ipv4-l3-protocol.h"
#include "arp-header.h"
#include "udp-header.h"
#include "ipv4-header.h"
namespace ns3 {
@@ -47,51 +41,17 @@ void
AsciiTrace::TraceAllQueues (void)
{
Packet::EnableMetadata ();
TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/*",
TraceRoot::Connect ("/nodes/*/devices/*/queue/*",
MakeCallback (&AsciiTrace::LogDevQueue, this));
}
void
AsciiTrace::TraceAllNetDeviceRx (void)
{
Packet::EnableMetadata ();
TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/rx",
TraceRoot::Connect ("/nodes/*/devices/*/rx",
MakeCallback (&AsciiTrace::LogDevRx, this));
}
void
AsciiTrace::PrintType (Packet const &packet)
{
Packet p = packet;
LlcSnapHeader llc;
p.RemoveHeader (llc);
switch (llc.GetType ())
{
case 0x0800: {
Ipv4Header ipv4;
p.RemoveHeader (ipv4);
if (ipv4.GetProtocol () == 17)
{
UdpHeader udp;
p.RemoveHeader (udp);
m_os << "udp size=" << p.GetSize ();
}
} break;
case 0x0806: {
ArpHeader arp;
p.RemoveHeader (arp);
m_os << "arp ";
if (arp.IsRequest ())
{
m_os << "request";
}
else
{
m_os << "reply ";
}
} break;
}
}
void
AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet)
{
@@ -113,9 +73,9 @@ AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet)
NodeList::NodeIndex nodeIndex;
context.Get (nodeIndex);
m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
Ipv4L3Protocol::InterfaceIndex interfaceIndex;
context.Get (interfaceIndex);
m_os << "interface=" << interfaceIndex << " ";
Node::NetDeviceIndex deviceIndex;
context.Get (deviceIndex);
m_os << "device=" << deviceIndex << " ";
m_os << "pkt-uid=" << packet.GetUid () << " ";
packet.Print (m_os);
m_os << std::endl;
@@ -127,9 +87,9 @@ AsciiTrace::LogDevRx (TraceContext const &context, Packet &p)
NodeList::NodeIndex nodeIndex;
context.Get (nodeIndex);
m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
Ipv4L3Protocol::InterfaceIndex interfaceIndex;
context.Get (interfaceIndex);
m_os << "interface=" << interfaceIndex << " ";
Node::NetDeviceIndex deviceIndex;
context.Get (deviceIndex);
m_os << "device=" << deviceIndex << " ";
m_os << "pkt-uid=" << p.GetUid () << " ";
p.Print (m_os);
m_os << std::endl;

View File

@@ -37,7 +37,6 @@ public:
void TraceAllQueues (void);
void TraceAllNetDeviceRx (void);
private:
void PrintType (Packet const &p);
void LogDevQueue (TraceContext const &context, const Packet &p);
void LogDevRx (TraceContext const &context, Packet &p);
std::ofstream m_os;

View File

@@ -23,17 +23,15 @@
#include "ns3/composite-trace-resolver.h"
#include "ns3/net-device.h"
#include "ns3/callback.h"
#include "l3-demux.h"
#include "ipv4-l4-demux.h"
#include "internet-node.h"
#include "udp-l4-protocol.h"
#include "ipv4-l3-protocol.h"
#include "arp-l3-protocol.h"
#include "udp-impl.h"
#include "arp-private.h"
#include "ipv4-impl.h"
#include "ipv4-private.h"
namespace ns3 {
@@ -55,38 +53,35 @@ InternetNode::Construct (void)
{
Ptr<Ipv4L3Protocol> ipv4 = Create<Ipv4L3Protocol> (this);
Ptr<ArpL3Protocol> arp = Create<ArpL3Protocol> (this);
Ptr<UdpL4Protocol> udp = Create<UdpL4Protocol> (this);
// XXX remove the PeekPointer below.
RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, PeekPointer (ipv4)),
Ipv4L3Protocol::PROT_NUMBER, 0);
RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (arp)),
ArpL3Protocol::PROT_NUMBER, 0);
Ptr<L3Demux> l3Demux = Create<L3Demux> (this);
Ptr<Ipv4L4Demux> ipv4L4Demux = Create<Ipv4L4Demux> (this);
l3Demux->Insert (ipv4);
l3Demux->Insert (arp);
Ptr<UdpL4Protocol> udp = Create<UdpL4Protocol> (this);
ipv4L4Demux->Insert (udp);
Ptr<UdpImpl> udpImpl = Create<UdpImpl> (udp);
Ptr<ArpPrivate> arpPrivate = Create<ArpPrivate> (arp);
Ptr<Ipv4Impl> ipv4Impl = Create<Ipv4Impl> (ipv4);
Ptr<Ipv4Private> ipv4Private = Create<Ipv4Private> (ipv4);
Object::AddInterface (ipv4Private);
Object::AddInterface (ipv4);
Object::AddInterface (arp);
Object::AddInterface (ipv4Impl);
Object::AddInterface (arpPrivate);
Object::AddInterface (udpImpl);
Object::AddInterface (l3Demux);
Object::AddInterface (ipv4L4Demux);
}
TraceResolver *
InternetNode::DoCreateTraceResolver (TraceContext const &context)
void
InternetNode::DoFillTraceResolver (CompositeTraceResolver &resolver)
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
Ptr<Ipv4Private> ipv4 = QueryInterface<Ipv4Private> (Ipv4Private::iid);
resolver->Add ("ipv4",
MakeCallback (&Ipv4Private::CreateTraceResolver, PeekPointer (ipv4)),
InternetNode::IPV4);
return resolver;
Node::DoFillTraceResolver (resolver);
Ptr<Ipv4L3Protocol> ipv4 = QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
resolver.Add ("ipv4",
MakeCallback (&Ipv4L3Protocol::CreateTraceResolver, PeekPointer (ipv4)),
InternetNode::IPV4);
}
void
@@ -95,25 +90,4 @@ InternetNode::DoDispose()
Node::DoDispose ();
}
void
InternetNode::DoAddDevice (Ptr<NetDevice> device)
{
device->SetReceiveCallback (MakeCallback (&InternetNode::ReceiveFromDevice, this));
}
bool
InternetNode::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const
{
Ptr<L3Demux> demux = QueryInterface<L3Demux> (L3Demux::iid);
Ptr<L3Protocol> target = demux->GetProtocol (protocolNumber);
if (target != 0)
{
Packet packet = p;
target->Receive(packet, device);
return true;
}
return false;
}
}//namespace ns3

View File

@@ -46,8 +46,7 @@ public:
protected:
virtual void DoDispose(void);
private:
virtual void DoAddDevice (Ptr<NetDevice> device);
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
virtual void DoFillTraceResolver (CompositeTraceResolver &resolver);
bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &p, uint16_t protocolNumber) const;
void Construct (void);
};

View File

@@ -41,15 +41,16 @@ NS_DEBUG_COMPONENT_DEFINE ("Ipv4L3Protocol");
namespace ns3 {
const InterfaceId Ipv4L3Protocol::iid = MakeInterfaceId ("Ipv4L3Protocol", Object::iid);
const uint16_t Ipv4L3Protocol::PROT_NUMBER = 0x0800;
Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
: L3Protocol (PROT_NUMBER, 4),
m_nInterfaces (0),
: m_nInterfaces (0),
m_defaultTtl (64),
m_identification (0),
m_node (node)
{
SetInterfaceId (Ipv4L3Protocol::iid);
m_staticRouting = Create<Ipv4StaticRouting> ();
AddRoutingProtocol (m_staticRouting, 0);
SetupLoopback ();
@@ -66,9 +67,9 @@ Ipv4L3Protocol::DoDispose (void)
}
m_interfaces.clear ();
m_node = 0;
L3Protocol::DoDispose ();
m_staticRouting->Dispose ();
m_staticRouting = 0;
Object::DoDispose ();
}
void
@@ -98,8 +99,8 @@ Ipv4L3Protocol::CreateTraceResolver (TraceContext const &context)
TraceResolver *
Ipv4L3Protocol::InterfacesCreateTraceResolver (TraceContext const &context) const
{
ArrayTraceResolver<Ipv4Interface> *resolver =
new ArrayTraceResolver<Ipv4Interface>
ArrayTraceResolver<Ipv4Interface *> *resolver =
new ArrayTraceResolver<Ipv4Interface *>
(context,
MakeCallback (&Ipv4L3Protocol::GetNInterfaces, this),
MakeCallback (&Ipv4L3Protocol::GetInterface, this));
@@ -240,18 +241,19 @@ Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
}
void
Ipv4L3Protocol::Receive(Packet& packet, Ptr<NetDevice> device)
Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from)
{
uint32_t index = 0;
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
{
if ((*i)->GetDevice () == device)
{
m_rxTrace (packet, index);
m_rxTrace (p, index);
break;
}
index++;
}
Packet packet = p;
Ipv4Header ipHeader;
packet.RemoveHeader (ipHeader);

View File

@@ -30,7 +30,6 @@
#include "ipv4-header.h"
#include "ns3/ptr.h"
#include "ns3/ipv4.h"
#include "l3-protocol.h"
#include "ipv4-static-routing.h"
namespace ns3 {
@@ -46,9 +45,10 @@ class TraceResolver;
class TraceContext;
class Ipv4L3Protocol : public L3Protocol
class Ipv4L3Protocol : public Object
{
public:
static const InterfaceId iid;
static const uint16_t PROT_NUMBER;
enum TraceType {
@@ -57,7 +57,7 @@ public:
DROP,
INTERFACES,
};
typedef ArrayTraceResolver<Ipv4Interface>::Index InterfaceIndex;
typedef ArrayTraceResolver<Ipv4Interface *>::Index InterfaceIndex;
Ipv4L3Protocol(Ptr<Node> node);
virtual ~Ipv4L3Protocol ();
@@ -95,7 +95,7 @@ public:
* - implement a per-NetDevice ARP cache
* - send back arp replies on the right device
*/
virtual void Receive(Packet& p, Ptr<NetDevice> device);
void Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from);
/**
* \param packet packet to send

View File

@@ -23,7 +23,7 @@
#include "ns3/net-device.h"
#include "ns3/node.h"
#include "ipv4-loopback-interface.h"
#include "ipv4-private.h"
#include "ipv4-l3-protocol.h"
namespace ns3 {
@@ -43,8 +43,8 @@ Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context)
void
Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
{
Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
ipv4->Receive (packet, GetDevice ());
Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ()->GetAddress ());
}
}//namespace ns3

View File

@@ -1,67 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ipv4-private.h"
#include "ipv4-l3-protocol.h"
#include "ns3/assert.h"
#include "ns3/net-device.h"
namespace ns3 {
const InterfaceId Ipv4Private::iid = MakeInterfaceId ("Ipv4Private", Object::iid);
Ipv4Private::Ipv4Private (Ptr<Ipv4L3Protocol> ipv4)
: m_ipv4 (ipv4)
{
SetInterfaceId (Ipv4Private::iid);
}
Ipv4Private::~Ipv4Private ()
{
NS_ASSERT (m_ipv4 == 0);
}
TraceResolver *
Ipv4Private::CreateTraceResolver (TraceContext const &context)
{
return m_ipv4->CreateTraceResolver (context);
}
void
Ipv4Private::Send (Packet const &packet, Ipv4Address source,
Ipv4Address destination, uint8_t protocol)
{
m_ipv4->Send (packet, source, destination, protocol);
}
Ipv4Interface *
Ipv4Private::FindInterfaceForDevice (Ptr<const NetDevice>device)
{
return m_ipv4->FindInterfaceForDevice (device);
}
void
Ipv4Private::Receive(Packet& p, Ptr<NetDevice> device)
{
m_ipv4->Receive (p, device);
}
void
Ipv4Private::DoDispose (void)
{
m_ipv4 = 0;
Object::DoDispose ();
}
} // namespace ns3

View File

@@ -1,58 +0,0 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef IPV4_PRIVATE_H
#define IPV4_PRIVATE_H
#include "ns3/object.h"
#include "ns3/ipv4-address.h"
#include "ns3/ptr.h"
#include <stdint.h>
namespace ns3 {
class Packet;
class Ipv4L3Protocol;
class TraceContext;
class TraceResolver;
class Ipv4Interface;
class NetDevice;
class Ipv4Private : public Object
{
public:
static const InterfaceId iid;
Ipv4Private (Ptr<Ipv4L3Protocol> ipv4);
virtual ~Ipv4Private ();
TraceResolver *CreateTraceResolver (TraceContext const &context);
void Send (Packet const &packet, Ipv4Address source,
Ipv4Address destination, uint8_t protocol);
Ipv4Interface *FindInterfaceForDevice (Ptr<const NetDevice>device);
void Receive(Packet& p, Ptr<NetDevice> device);
protected:
virtual void DoDispose (void);
private:
Ptr<Ipv4L3Protocol> m_ipv4;
};
} // namespace ns3
#endif /* IPV4_PRIVATE_H */

View File

@@ -31,7 +31,6 @@
#include "ipv4-header.h"
#include "ns3/ptr.h"
#include "ns3/ipv4.h"
#include "l3-protocol.h"
namespace ns3 {

View File

@@ -1,90 +0,0 @@
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// 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: George F. Riley<riley@ece.gatech.edu>
//
// Implement the L3Protocols capability for ns3.
// George F. Riley, Georgia Tech, Fall 2006
#include <sstream>
#include <string>
#include "ns3/composite-trace-resolver.h"
#include "ns3/node.h"
#include "l3-demux.h"
#include "l3-protocol.h"
namespace ns3 {
const InterfaceId L3Demux::iid = MakeInterfaceId ("L3Demux", Object::iid);
L3Demux::L3Demux (Ptr<Node> node)
: m_node (node)
{
SetInterfaceId (L3Demux::iid);
}
L3Demux::~L3Demux()
{}
void
L3Demux::DoDispose (void)
{
for (L3Map_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{
i->second->Dispose ();
i->second = 0;
}
m_protocols.clear ();
m_node = 0;
Object::DoDispose ();
}
TraceResolver *
L3Demux::CreateTraceResolver (TraceContext const &context) const
{
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
for (L3Map_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
{
std::string protValue;
std::ostringstream oss (protValue);
oss << i->second->GetProtocolNumber ();
ProtocolTraceType context = i->second->GetProtocolNumber ();
resolver->Add (protValue,
MakeCallback (&L3Protocol::CreateTraceResolver, PeekPointer (i->second)),
context);
}
return resolver;
}
void L3Demux::Insert(Ptr<L3Protocol> p)
{
m_protocols.insert(L3Map_t::value_type(p->GetProtocolNumber (), p));
}
Ptr<L3Protocol>
L3Demux::GetProtocol (int p)
{ // Look up a protocol by protocol number
L3Map_t::iterator i = m_protocols.find(p);
if (i == m_protocols.end())
{
return 0;
}
return i->second; // Return the protocol
}
} //namespace ns3

View File

@@ -1,93 +0,0 @@
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// 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: George F. Riley<riley@ece.gatech.edu>
//
// Define the L3Protocols capability for ns3.
// George F. Riley, Georgia Tech, Fall 2006
// This object manages the different layer 3 protocols for any ns3
// node that has this capability.
#ifndef L3_DEMUX_H
#define L3_DEMUX_H
#include <map>
#include "ns3/object.h"
#include "ns3/ptr.h"
namespace ns3 {
class L3Protocol;
class Node;
class TraceResolver;
class TraceContext;
/**
* \brief L3 Demux
*/
class L3Demux : public Object
{
public:
static const InterfaceId iid;
typedef int ProtocolTraceType;
L3Demux(Ptr<Node> node);
virtual ~L3Demux();
/**
* \param context the trace context to use to construct the
* TraceResolver to return
* \returns a TraceResolver which can resolve all traces
* performed in this object. The caller must
* delete the returned object.
*/
TraceResolver *CreateTraceResolver (TraceContext const &context) const;
/**
* \param protocol a template for the protocol to add to this L3 Demux.
*
* Invoke Copy on the input template to get a copy of the input
* protocol which can be used on the Node on which this L3 Demux
* is running. The new L3Protocol is registered internally as
* a working L3 Protocol and returned from this method.
* The caller does not get ownership of the returned pointer.
*/
void Insert(Ptr<L3Protocol> protocol);
/**
* \param protocolNumber number of protocol to lookup
* in this L4 Demux
* \returns a matching L3 Protocol
*
* This method is typically called by lower layers
* to forward packets up the stack to the right protocol.
* It is also called from NodeImpl::GetIpv4 for example.
*/
Ptr<L3Protocol> GetProtocol (int protocolNumber);
protected:
virtual void DoDispose (void);
private:
typedef std::map<int, Ptr<ns3::L3Protocol> > L3Map_t;
Ptr<Node> m_node;
L3Map_t m_protocols;
};
} //namespace ns3
#endif

View File

@@ -1,54 +0,0 @@
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// 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: George F. Riley<riley@ece.gatech.edu>
//
// NS3 - Layer 3 Protocol base class
// George F. Riley, Georgia Tech, Spring 2007
#include "l3-protocol.h"
namespace ns3 {
L3Protocol::L3Protocol(int protocolNumber, int version)
: m_protocolNumber (protocolNumber),
m_version (version)
{}
L3Protocol::~L3Protocol ()
{}
int
L3Protocol::GetProtocolNumber (void) const
{
return m_protocolNumber;
}
int
L3Protocol::GetVersion() const
{
return m_version;
}
void
L3Protocol::DoDispose (void)
{
Object::DoDispose ();
}
}//namespace ns3

View File

@@ -1,73 +0,0 @@
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// 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: George F. Riley<riley@ece.gatech.edu>
//
// NS3 - Layer 3 Protocol base class
// George F. Riley, Georgia Tech, Spring 2007
#ifndef L3_PROTOCOL_H
#define L3_PROTOCOL_H
#include "ns3/object.h"
#include "ns3/ptr.h"
namespace ns3 {
class Packet;
class NetDevice;
class TraceResolver;
class TraceContext;
/**
* ::Send is always defined in subclasses.
*/
class L3Protocol : public Object {
public:
L3Protocol(int protocolNumber, int version);
virtual ~L3Protocol ();
/**
* \return The protocol number of this Layer 3 protocol
*/
int GetProtocolNumber (void) const;
/**
* \return The version number of this protocol
*/
int GetVersion() const;
virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
/**
* Lower layer calls this method after calling L3Demux::Lookup
* The ARP subclass needs to know from which NetDevice this
* packet is coming to:
* - implement a per-NetDevice ARP cache
* - send back arp replies on the right device
*/
virtual void Receive(Packet& p, Ptr<NetDevice> device) = 0;
protected:
virtual void DoDispose (void);
private:
int m_protocolNumber;
int m_version;
};
} // Namespace ns3
#endif

View File

@@ -29,8 +29,6 @@
#include "ipv4-end-point-demux.h"
#include "ipv4-end-point.h"
#include "ipv4-l3-protocol.h"
#include "ipv4-private.h"
#include "l3-demux.h"
#include "udp-socket.h"
namespace ns3 {
@@ -138,7 +136,7 @@ UdpL4Protocol::Send (Packet packet,
packet.AddHeader (udpHeader);
Ptr<Ipv4Private> ipv4 = m_node->QueryInterface<Ipv4Private> (Ipv4Private::iid);
Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
if (ipv4 != 0)
{
ipv4->Send (packet, saddr, daddr, PROT_NUMBER);

View File

@@ -19,6 +19,7 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns3/node.h"
#include "ns3/inet-socket-address.h"
#include "udp-socket.h"
#include "udp-l4-protocol.h"
#include "ipv4-end-point.h"
@@ -72,12 +73,12 @@ UdpSocket::Destroy (void)
int
UdpSocket::FinishBind (void)
{
m_endPoint->SetRxCallback (MakeCallback (&UdpSocket::ForwardUp, this));
m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocket::Destroy, this));
if (m_endPoint == 0)
{
return -1;
}
m_endPoint->SetRxCallback (MakeCallback (&UdpSocket::ForwardUp, this));
m_endPoint->SetDestroyCallback (MakeCallback (&UdpSocket::Destroy, this));
return 0;
}
@@ -88,21 +89,32 @@ UdpSocket::Bind (void)
return FinishBind ();
}
int
UdpSocket::Bind (Ipv4Address address)
UdpSocket::Bind (const Address &address)
{
m_endPoint = m_udp->Allocate (address);
return FinishBind ();
}
int
UdpSocket::Bind (uint16_t port)
{
m_endPoint = m_udp->Allocate (port);
return FinishBind ();
}
int
UdpSocket::Bind (Ipv4Address address, uint16_t port)
{
m_endPoint = m_udp->Allocate (address, port);
if (!InetSocketAddress::IsMatchingType (address))
{
return ERROR_INVAL;
}
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
if (ipv4 == Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_udp->Allocate ();
}
else if (ipv4 == Ipv4Address::GetAny () && port != 0)
{
m_endPoint = m_udp->Allocate (port);
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
m_endPoint = m_udp->Allocate (ipv4);
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
m_endPoint = m_udp->Allocate (ipv4, port);
}
return FinishBind ();
}
@@ -124,34 +136,36 @@ UdpSocket::ShutdownRecv (void)
return 0;
}
void
UdpSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
int
UdpSocket::DoClose(Callback<void, Ptr<Socket> > closeCompleted)
{
// XXX: we should set the close state and check it in all API methods.
if (!closeCompleted.IsNull ())
{
closeCompleted (this);
}
return 0;
}
void
UdpSocket::DoConnect(const Ipv4Address & address,
uint16_t portNumber,
ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
ns3::Callback<void, Ptr<Socket> > connectionFailed,
ns3::Callback<void, Ptr<Socket> > halfClose)
int
UdpSocket::DoConnect(const Address & address,
Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose)
{
m_defaultAddress = address;
m_defaultPort = portNumber;
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
m_defaultAddress = transport.GetIpv4 ();
m_defaultPort = transport.GetPort ();
if (!connectionSucceeded.IsNull ())
{
connectionSucceeded (this);
}
m_connected = true;
return 0;
}
int
UdpSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
ns3::Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
ns3::Callback<void, Ptr<Socket> > closeRequested)
UdpSocket::DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
Callback<void, Ptr<Socket> > closeRequested)
{
// calling accept on a udp socket is a programming error.
m_errno = ERROR_OPNOTSUPP;
@@ -160,7 +174,7 @@ UdpSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_
int
UdpSocket::DoSend (const uint8_t* buffer,
uint32_t size,
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
if (!m_connected)
{
@@ -179,8 +193,17 @@ UdpSocket::DoSend (const uint8_t* buffer,
return DoSendPacketTo (p, m_defaultAddress, m_defaultPort, dataSent);
}
int
UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
UdpSocket::DoSendPacketTo (const Packet &p, const Address &address,
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
return DoSendPacketTo (p, ipv4, port, dataSent);
}
int
UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address ipv4, uint16_t port,
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
if (m_endPoint == 0)
{
@@ -196,8 +219,8 @@ UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
m_errno = ERROR_SHUTDOWN;
return -1;
}
m_udp->Send (p, m_endPoint->GetLocalAddress (), daddr,
m_endPoint->GetLocalPort (), dport);
m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4,
m_endPoint->GetLocalPort (), port);
if (!dataSent.IsNull ())
{
dataSent (this, p.GetSize ());
@@ -205,11 +228,10 @@ UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
return 0;
}
int
UdpSocket::DoSendTo(const Ipv4Address &address,
uint16_t port,
UdpSocket::DoSendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
if (m_connected)
{
@@ -225,34 +247,39 @@ UdpSocket::DoSendTo(const Ipv4Address &address,
{
p = Packet (buffer, size);
}
return DoSendPacketTo (p, address, port, dataSent);
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
return DoSendPacketTo (p, ipv4, port, dataSent);
}
void
UdpSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
UdpSocket::DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
{
m_rxCallback = callback;
}
void
UdpSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> callback)
UdpSocket::DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
{
m_dummyRxCallback = callback;
}
void
UdpSocket::ForwardUp (const Packet &packet, Ipv4Address saddr, uint16_t sport)
UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port)
{
if (m_shutdownRecv)
{
return;
}
Address address = InetSocketAddress (ipv4, port);
Packet p = packet;
if (!m_dummyRxCallback.IsNull ())
{
m_dummyRxCallback (this, p.GetSize (), saddr, sport);
m_dummyRxCallback (this, p.GetSize (), address);
}
if (!m_rxCallback.IsNull ())
{
m_rxCallback (this, p.PeekData (), p.GetSize (), saddr, sport);
m_rxCallback (this, p.PeekData (), p.GetSize (), address);
}
}

View File

@@ -25,6 +25,7 @@
#include "ns3/callback.h"
#include "ns3/socket.h"
#include "ns3/ptr.h"
#include "ns3/ipv4-address.h"
namespace ns3 {
@@ -45,49 +46,47 @@ public:
virtual enum SocketErrno GetErrno (void) const;
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
virtual int Bind (Ipv4Address address);
virtual int Bind (uint16_t port);
virtual int Bind (Ipv4Address address, uint16_t port);
virtual int Bind (const Address &address);
virtual int ShutdownSend (void);
virtual int ShutdownRecv (void);
private:
virtual void DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted);
virtual void DoConnect(const Ipv4Address & address,
uint16_t portNumber,
ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
ns3::Callback<void, Ptr<Socket> > connectionFailed,
ns3::Callback<void, Ptr<Socket> > halfClose);
virtual int DoAccept(ns3::Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
ns3::Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
ns3::Callback<void, Ptr<Socket> > closeRequested);
virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
virtual int DoConnect(const Address & address,
Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose);
virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
Callback<void, Ptr<Socket> > closeRequested);
virtual int DoSend (const uint8_t* buffer,
uint32_t size,
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual int DoSendTo(const Ipv4Address &address,
uint16_t port,
Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual int DoSendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual void DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t>);
virtual void DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t>);
Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&>);
virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
private:
friend class Udp;
// invoked by Udp class
int FinishBind (void);
void ForwardUp (const Packet &p, Ipv4Address saddr, uint16_t sport);
void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port);
void Destroy (void);
int DoSendPacketTo (const Packet &p, const Address &daddr,
Callback<void, Ptr<Socket>, uint32_t> dataSent);
int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent);
Callback<void, Ptr<Socket>, uint32_t> dataSent);
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
Ptr<UdpL4Protocol> m_udp;
Ipv4Address m_defaultAddress;
uint16_t m_defaultPort;
Callback<void,Ptr<Socket>,uint32_t,const Ipv4Address &,uint16_t> m_dummyRxCallback;
Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Ipv4Address &,uint16_t> m_rxCallback;
Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
Callback<void,Ptr<Socket>,uint8_t const*,uint32_t,const Address &> m_rxCallback;
enum SocketErrno m_errno;
bool m_shutdownSend;
bool m_shutdownRecv;

View File

@@ -8,8 +8,6 @@ def build(bld):
obj.uselib_local = ['ns3-node', 'ns3-applications']
obj.source = [
'internet-node.cc',
'l3-demux.cc',
'l3-protocol.cc',
'ipv4-l4-demux.cc',
'ipv4-l4-protocol.cc',
'ipv4-header.cc',
@@ -27,9 +25,7 @@ def build(bld):
'ipv4-loopback-interface.cc',
'udp-socket.cc',
'ipv4-end-point-demux.cc',
'arp-private.cc',
'ipv4-impl.cc',
'ipv4-private.cc',
'ascii-trace.cc',
'pcap-trace.cc',
'udp-impl.cc',

View File

@@ -26,24 +26,34 @@ void WriteTo (Buffer::Iterator &i, Ipv4Address ad)
{
i.WriteHtonU32 (ad.GetHostOrder ());
}
void WriteTo (Buffer::Iterator &i, MacAddress ad)
void WriteTo (Buffer::Iterator &i, const Address &ad)
{
uint8_t mac[MacAddress::MAX_LEN];
ad.Peek (mac);
uint8_t mac[Address::MAX_SIZE];
ad.CopyTo (mac);
i.Write (mac, ad.GetLength ());
}
void WriteTo (Buffer::Iterator &i, Eui48Address ad)
{
uint8_t mac[6];
ad.CopyTo (mac);
i.Write (mac, 6);
}
void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
{
ad.SetHostOrder (i.ReadNtohU32 ());
}
void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len)
void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len)
{
uint8_t mac[MacAddress::MAX_LEN];
uint8_t mac[Address::MAX_SIZE];
i.Read (mac, len);
ad.Set (mac, len);
ad.CopyFrom (mac, len);
}
void ReadFrom (Buffer::Iterator &i, Eui48Address &ad)
{
uint8_t mac[6];
i.Read (mac, 6);
ad.CopyFrom (mac);
}
}; // namespace ns3
} // namespace ns3

View File

@@ -22,16 +22,19 @@
#define ADDRESS_UTILS_H
#include "ns3/buffer.h"
#include "ns3/ipv4-address.h"
#include "ns3/mac-address.h"
#include "ipv4-address.h"
#include "address.h"
#include "eui48-address.h"
namespace ns3 {
void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
void WriteTo (Buffer::Iterator &i, MacAddress ad);
void WriteTo (Buffer::Iterator &i, const Address &ad);
void WriteTo (Buffer::Iterator &i, Eui48Address ad);
void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len);
void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len);
void ReadFrom (Buffer::Iterator &i, Eui48Address &ad);
};

164
src/node/address.cc Normal file
View File

@@ -0,0 +1,164 @@
#include "ns3/assert.h"
#include "address.h"
#include <iostream>
#include <iomanip>
namespace ns3 {
Address::Address ()
: m_type (0),
m_len (0)
{
memset (m_data, 0, m_len);
}
Address::Address (uint8_t type, const uint8_t *buffer, uint8_t len)
: m_type (type),
m_len (len)
{
NS_ASSERT (m_len <= MAX_SIZE);
memset (m_data, 0, m_len);
memcpy (m_data, buffer, m_len);
}
Address::Address (const Address & address)
: m_type (address.m_type),
m_len (address.m_len)
{
NS_ASSERT (m_len <= MAX_SIZE);
memset (m_data, 0, m_len);
memcpy (m_data, address.m_data, m_len);
}
Address &
Address::operator = (const Address &address)
{
NS_ASSERT (m_len <= MAX_SIZE);
m_type = address.m_type;
m_len = address.m_len;
NS_ASSERT (m_len <= MAX_SIZE);
memset (m_data, 0, m_len);
memcpy (m_data, address.m_data, m_len);
return *this;
}
bool
Address::IsInvalid (void) const
{
return m_len == 0 && m_type == 0;
}
uint8_t
Address::GetLength (void) const
{
NS_ASSERT (m_len <= MAX_SIZE);
return m_len;
}
uint32_t
Address::CopyTo (uint8_t buffer[MAX_SIZE]) const
{
NS_ASSERT (m_len <= MAX_SIZE);
memcpy (buffer, m_data, m_len);
return m_len;
}
uint32_t
Address::CopyAllTo (uint8_t *buffer, uint8_t len) const
{
NS_ASSERT (len >= m_len + 2);
buffer[0] = m_type;
buffer[1] = m_len;
memcpy (buffer + 2, m_data, m_len);
return m_len + 2;
}
uint32_t
Address::CopyFrom (const uint8_t *buffer, uint8_t len)
{
NS_ASSERT (len <= MAX_SIZE);
memcpy (m_data, buffer, len);
m_len = len;
return m_len;
}
uint32_t
Address::CopyAllFrom (const uint8_t *buffer, uint8_t len)
{
NS_ASSERT (len >= 2);
m_type = buffer[0];
m_len = buffer[1];
NS_ASSERT (len >= m_len + 2);
memcpy (m_data, buffer + 2, m_len);
return m_len + 2;
}
bool
Address::CheckCompatible (uint8_t type, uint8_t len) const
{
NS_ASSERT (len <= MAX_SIZE);
return m_len == len && (m_type == type || m_type == 0);
}
bool
Address::IsMatchingType (uint8_t type) const
{
return m_type == type;
}
uint8_t
Address::Register (void)
{
static uint8_t type = 1;
type++;
return type;
}
bool operator == (const Address &a, const Address &b)
{
NS_ASSERT (a.m_type == b.m_type ||
a.m_type == 0 ||
b.m_type == 0);
NS_ASSERT (a.GetLength() == b.GetLength());
return memcmp (a.m_data, b.m_data, a.m_len) == 0;
}
bool operator != (const Address &a, const Address &b)
{
return !(a == b);
}
bool operator < (const Address &a, const Address &b)
{
NS_ASSERT (a.m_type == b.m_type ||
a.m_type == 0 ||
b.m_type == 0);
NS_ASSERT (a.GetLength() == b.GetLength());
for (uint8_t i = 0; i < a.GetLength(); i++)
{
if (a.m_data[i] < b.m_data[i])
{
return true;
}
else if (a.m_data[i] > b.m_data[i])
{
return false;
}
}
return false;
}
std::ostream& operator<< (std::ostream& os, const Address & address)
{
if (address.m_len == 0)
{
os << "NULL-ADDRESS";
return os;
}
os.setf (std::ios::hex, std::ios::basefield);
std::cout.fill('0');
for (uint8_t i=0; i < (address.m_len-1); i++)
{
os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
}
// Final byte not suffixed by ":"
os << std::setw(2) << (uint32_t)address.m_data[address.m_len-1];
os.setf (std::ios::dec, std::ios::basefield);
std::cout.fill(' ');
return os;
}
} // namespace ns3

172
src/node/address.h Normal file
View File

@@ -0,0 +1,172 @@
#ifndef ADDRESS_H
#define ADDRESS_H
#include <stdint.h>
#include <ostream>
namespace ns3 {
/**
* \brief a polymophic address class
*
* This class is very similar in design and spirit to the BSD sockaddr
* structure: they are both used to hold multiple types of addresses
* together with the type of the address.
*
* A new address class defined by a user needs to:
* - allocate a type id with Address::Register
* - provide a method to convert his new address to an Address
* instance. This method is typically a member method named ConvertTo:
* Address MyAddress::ConvertTo (void) const;
* - provide a method to convert an Address instance back to
* an instance of his new address type. This method is typically
* a static member method of his address class named ConvertFrom:
* static MyAddress MyAddress::ConvertFrom (const Address &address);
* - the ConvertFrom method is expected to check that the type of the
* input Address instance is compatible with its own type.
*
* Typical code to create a new class type looks like:
* \code
* // this class represents addresses which are 2 bytes long.
* class MyAddress
* {
* public:
* Address ConvertTo (void) const;
* static MyAddress ConvertFrom (void);
* private:
* static uint8_t GetType (void);
* };
*
* Address MyAddress::ConvertTo (void) const
* {
* return Address (GetType (), m_buffer, 2);
* }
* MyAddress MyAddress::ConvertFrom (const Address &address)
* {
* MyAddress ad;
* NS_ASSERT (address.CheckCompatible (GetType (), 2));
* address.CopyTo (ad.m_buffer, 2);
* return ad;
* }
* uint8_t MyAddress::GetType (void)
* {
* static uint8_t type = Address::Register ();
* return type;
* }
* \endcode
*/
class Address
{
public:
enum {
/**
* The maximum size of a byte buffer which
* can be stored in an Address instance.
*/
MAX_SIZE = 30
};
/**
* Create an invalid address
*/
Address ();
/**
* \param type the type of the Address to create
* \param buffer a pointer to a buffer of bytes which hold
* a serialized representation of the address in network
* byte order.
* \param len the length of the buffer.
*
* Create an address from a type and a buffer. This constructor
* is typically invoked from the conversion functions of various
* address types when they have to convert themselves to an
* Address instance.
*/
Address (uint8_t type, const uint8_t *buffer, uint8_t len);
Address (const Address & address);
Address &operator = (const Address &address);
/**
* \returns true if this address is invalid, false otherwise.
*
* An address is invalid if and only if it was created
* through the default constructor and it was never
* re-initialized.
*/
bool IsInvalid (void) const;
/**
* \returns the length of the underlying address.
*/
uint8_t GetLength (void) const;
/**
* \param buffer buffer to copy the address bytes to.
* \returns the number of bytes copied.
*/
uint32_t CopyTo (uint8_t buffer[MAX_SIZE]) const;
/**
* \param buffer buffer to copy the whole address data structure to
* \param len the size of the buffer
* \returns the number of bytes copied.
*/
uint32_t CopyAllTo (uint8_t *buffer, uint8_t len) const;
/**
* \param buffer pointer to a buffer of bytes which contain
* a serialized representation of the address in network
* byte order.
* \param len length of buffer
* \returns the number of bytes copied.
*
* Copy the input buffer to the internal buffer of this address
* instance.
*/
uint32_t CopyFrom (const uint8_t *buffer, uint8_t len);
/**
* \param buffer pointer to a buffer of bytes which contain
* a copy of all the members of this Address class.
* \param len the length of the buffer
* \returns the number of bytes copied.
*/
uint32_t CopyAllFrom (const uint8_t *buffer, uint8_t len);
/**
* \param type a type id as returned by Address::Register
* \param len the length associated to this type id.
*
* \returns true if the type of the address stored internally
* is compatible with the requested type, false otherwise.
*/
bool CheckCompatible (uint8_t type, uint8_t len) const;
/**
* \param type a type id as returned by Address::Register
* \returns true if the type of the address stored internally
* is compatible with the requested type, false otherwise.
*
* This method checks that the types are _exactly_ equal.
* This method is really used only by the PacketSocketAddress
* and there is little point in using it otherwise so,
* you have been warned: DO NOT USE THIS METHOD.
*/
bool IsMatchingType (uint8_t type) const;
/**
* Allocate a new type id for a new type of address.
* \returns a new type id.
*/
static uint8_t Register (void);
private:
friend bool operator == (const Address &a, const Address &b);
friend bool operator < (const Address &a, const Address &b);
friend std::ostream& operator<< (std::ostream& os, const Address & address);
uint8_t m_type;
uint8_t m_len;
uint8_t m_data[MAX_SIZE];
};
bool operator == (const Address &a, const Address &b);
bool operator != (const Address &a, const Address &b);
bool operator < (const Address &a, const Address &b);
std::ostream& operator<< (std::ostream& os, const Address & address);
} // namespace ns3
#endif /* ADDRESS_H */

View File

@@ -74,22 +74,22 @@ EthernetHeader::GetPreambleSfd (void) const
}
void
EthernetHeader::SetSource (MacAddress source)
EthernetHeader::SetSource (Eui48Address source)
{
m_source = source;
}
MacAddress
Eui48Address
EthernetHeader::GetSource (void) const
{
return m_source;
}
void
EthernetHeader::SetDestination (MacAddress dst)
EthernetHeader::SetDestination (Eui48Address dst)
{
m_destination = dst;
}
MacAddress
Eui48Address
EthernetHeader::GetDestination (void) const
{
return m_destination;
@@ -147,8 +147,6 @@ EthernetHeader::SerializeTo (Buffer::Iterator start) const
{
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);
@@ -163,11 +161,11 @@ EthernetHeader::DeserializeFrom (Buffer::Iterator start)
m_enPreambleSfd = i.ReadU64 ();
}
ReadFrom (i, m_destination, MAC_ADDR_SIZE);
ReadFrom (i, m_source, MAC_ADDR_SIZE);
ReadFrom (i, m_destination);
ReadFrom (i, m_source);
m_lengthType = i.ReadU16 ();
return GetSerializedSize ();
}
}; // namespace ns3
} // namespace ns3

View File

@@ -23,8 +23,8 @@
#define ETHERNET_HEADER_H
#include "ns3/header.h"
#include "ns3/mac-address.h"
#include <string>
#include "ns3/eui48-address.h"
namespace ns3 {
@@ -70,11 +70,11 @@ public:
/**
* \param source The source address of this packet
*/
void SetSource (MacAddress source);
void SetSource (Eui48Address source);
/**
* \param destination The destination address of this packet.
*/
void SetDestination (MacAddress destination);
void SetDestination (Eui48Address destination);
/**
* \param preambleSfd The value that the preambleSfd field should take
*/
@@ -90,11 +90,11 @@ public:
/**
* \return The source address of this packet
*/
MacAddress GetSource (void) const;
Eui48Address GetSource (void) const;
/**
* \return The destination address of this packet
*/
MacAddress GetDestination (void) const;
Eui48Address GetDestination (void) const;
/**
* \return The value of the PreambleSfd field
*/
@@ -121,8 +121,8 @@ private:
bool m_enPreambleSfd;
uint64_t m_preambleSfd; /// Value of the Preamble/SFD fields
uint16_t m_lengthType; /// Length or type of the packet
MacAddress m_source; /// Source address
MacAddress m_destination; /// Destination address
Eui48Address m_source; /// Source address
Eui48Address m_destination; /// Destination address
};
}; // namespace ns3

168
src/node/eui48-address.cc Normal file
View File

@@ -0,0 +1,168 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "eui48-address.h"
#include "address.h"
#include "ns3/assert.h"
#include <iomanip>
#include <iostream>
namespace ns3 {
#define ASCII_a (0x41)
#define ASCII_z (0x5a)
#define ASCII_A (0x61)
#define ASCII_Z (0x7a)
#define ASCII_COLON (0x3a)
#define ASCII_ZERO (0x30)
static char
AsciiToLowCase (char c)
{
if (c >= ASCII_a && c <= ASCII_z) {
return c;
} else if (c >= ASCII_A && c <= ASCII_Z) {
return c + (ASCII_a - ASCII_A);
} else {
return c;
}
}
Eui48Address::Eui48Address ()
{
memset (m_address, 0, 6);
}
Eui48Address::Eui48Address (const char *str)
{
int i = 0;
while (*str != 0 && i < 6)
{
uint8_t byte = 0;
while (*str != ASCII_COLON && *str != 0)
{
byte <<= 4;
char low = AsciiToLowCase (*str);
if (low >= ASCII_a)
{
byte |= low - ASCII_a + 10;
}
else
{
byte |= low - ASCII_ZERO;
}
str++;
}
m_address[i] = byte;
i++;
if (*str == 0)
{
break;
}
str++;
}
NS_ASSERT (i == 6);
}
void
Eui48Address::CopyFrom (const uint8_t buffer[6])
{
memcpy (m_address, buffer, 6);
}
void
Eui48Address::CopyTo (uint8_t buffer[6]) const
{
memcpy (buffer, m_address, 6);
}
bool
Eui48Address::IsMatchingType (const Address &address)
{
return address.CheckCompatible (GetType (), 6);
}
Eui48Address::operator Address ()
{
return ConvertTo ();
}
Address
Eui48Address::ConvertTo (void) const
{
return Address (GetType (), m_address, 6);
}
Eui48Address
Eui48Address::ConvertFrom (const Address &address)
{
NS_ASSERT (address.CheckCompatible (GetType (), 6));
Eui48Address retval;
address.CopyTo (retval.m_address);
return retval;
}
Eui48Address
Eui48Address::Allocate (void)
{
static uint64_t id = 0;
id++;
Eui48Address address;
address.m_address[0] = (id >> 40) & 0xff;
address.m_address[1] = (id >> 32) & 0xff;
address.m_address[2] = (id >> 24) & 0xff;
address.m_address[3] = (id >> 16) & 0xff;
address.m_address[4] = (id >> 8) & 0xff;
address.m_address[5] = (id >> 0) & 0xff;
return address;
}
uint8_t
Eui48Address::GetType (void)
{
static uint8_t type = Address::Register ();
return type;
}
bool operator == (const Eui48Address &a, const Eui48Address &b)
{
uint8_t ada[6];
uint8_t adb[6];
a.CopyTo (ada);
b.CopyTo (adb);
return memcmp (ada, adb, 6) == 0;
}
bool operator != (const Eui48Address &a, const Eui48Address &b)
{
return ! (a == b);
}
std::ostream& operator<< (std::ostream& os, const Eui48Address & address)
{
uint8_t ad[6];
address.CopyTo (ad);
os.setf (std::ios::hex, std::ios::basefield);
std::cout.fill('0');
for (uint8_t i=0; i < 5; i++)
{
os << std::setw(2) << (uint32_t)ad[i] << ":";
}
// Final byte not suffixed by ":"
os << std::setw(2) << (uint32_t)ad[5];
os.setf (std::ios::dec, std::ios::basefield);
std::cout.fill(' ');
return os;
}
} // namespace ns3

99
src/node/eui48-address.h Normal file
View File

@@ -0,0 +1,99 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef EUI48_ADDRESS_H
#define EUI48_ADDRESS_H
#include <stdint.h>
#include <ostream>
namespace ns3 {
class Address;
/**
* \brief an EUI-48 address
*
* This class can contain 48 bit IEEE addresses.
*/
class Eui48Address
{
public:
Eui48Address ();
/**
* \param str a string representing the new Eui48Address
*
* The format of the string is "xx:xx:xx:xx:xx:xx"
*/
Eui48Address (const char *str);
/**
* \param buffer address in network order
*
* Copy the input address to our internal buffer.
*/
void CopyFrom (const uint8_t buffer[6]);
/**
* \param buffer address in network order
*
* Copy the internal address to the input buffer.
*/
void CopyTo (uint8_t buffer[6]) const;
/**
* \returns a new Address instance
*
* Convert an instance of this class to a polymorphic Address instance.
*/
operator Address ();
/**
* \param address a polymorphic address
* \returns a new Eui48Address from the polymorphic address
*
* This function performs a type check and asserts if the
* type of the input address is not compatible with an
* Eui48Address.
*/
static Eui48Address ConvertFrom (const Address &address);
/**
* \returns true if the address matches, false otherwise.
*/
static bool IsMatchingType (const Address &address);
/**
* Allocate a new Eui48Address.
*/
static Eui48Address Allocate (void);
private:
/**
* \returns a new Address instance
*
* Convert an instance of this class to a polymorphic Address instance.
*/
Address ConvertTo (void) const;
static uint8_t GetType (void);
uint8_t m_address[6];
};
bool operator == (const Eui48Address &a, const Eui48Address &b);
bool operator != (const Eui48Address &a, const Eui48Address &b);
std::ostream& operator<< (std::ostream& os, const Eui48Address & address);
} // namespace ns3
#endif /* EUI48_ADDRESS_H */

171
src/node/eui64-address.cc Normal file
View File

@@ -0,0 +1,171 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "eui64-address.h"
#include "address.h"
#include "ns3/assert.h"
#include <iomanip>
#include <iostream>
namespace ns3 {
#define ASCII_a (0x41)
#define ASCII_z (0x5a)
#define ASCII_A (0x61)
#define ASCII_Z (0x7a)
#define ASCII_COLON (0x3a)
#define ASCII_ZERO (0x30)
static char
AsciiToLowCase (char c)
{
if (c >= ASCII_a && c <= ASCII_z) {
return c;
} else if (c >= ASCII_A && c <= ASCII_Z) {
return c + (ASCII_a - ASCII_A);
} else {
return c;
}
}
Eui64Address::Eui64Address ()
{
memset (m_address, 0, 8);
}
Eui64Address::Eui64Address (const char *str)
{
int i = 0;
while (*str != 0 && i < 8)
{
uint8_t byte = 0;
while (*str != ASCII_COLON && *str != 0)
{
byte <<= 4;
char low = AsciiToLowCase (*str);
if (low >= ASCII_a)
{
byte |= low - ASCII_a + 10;
}
else
{
byte |= low - ASCII_ZERO;
}
str++;
}
m_address[i] = byte;
i++;
if (*str == 0)
{
break;
}
str++;
}
NS_ASSERT (i == 6);
}
void
Eui64Address::CopyFrom (const uint8_t buffer[8])
{
memcpy (m_address, buffer, 8);
}
void
Eui64Address::CopyTo (uint8_t buffer[8]) const
{
memcpy (buffer, m_address, 8);
}
bool
Eui64Address::IsMatchingType (const Address &address)
{
return address.CheckCompatible (GetType (), 8);
}
Eui64Address::operator Address ()
{
return ConvertTo ();
}
Eui64Address
Eui64Address::ConvertFrom (const Address &address)
{
NS_ASSERT (address.CheckCompatible (GetType (), 8));
Eui64Address retval;
address.CopyTo (retval.m_address);
return retval;
}
Address
Eui64Address::ConvertTo (void) const
{
return Address (GetType (), m_address, 8);
}
Eui64Address
Eui64Address::Allocate (void)
{
static uint64_t id = 0;
id++;
Eui64Address address;
address.m_address[0] = (id >> 56) & 0xff;
address.m_address[1] = (id >> 48) & 0xff;
address.m_address[2] = (id >> 40) & 0xff;
address.m_address[3] = (id >> 32) & 0xff;
address.m_address[4] = (id >> 24) & 0xff;
address.m_address[5] = (id >> 16) & 0xff;
address.m_address[6] = (id >> 8) & 0xff;
address.m_address[7] = (id >> 0) & 0xff;
return address;
}
uint8_t
Eui64Address::GetType (void)
{
static uint8_t type = Address::Register ();
return type;
}
bool operator == (const Eui64Address &a, const Eui64Address &b)
{
uint8_t ada[8];
uint8_t adb[8];
a.CopyTo (ada);
b.CopyTo (adb);
return memcmp (ada, adb, 8) == 0;
}
bool operator != (const Eui64Address &a, const Eui64Address &b)
{
return ! (a == b);
}
std::ostream& operator<< (std::ostream& os, const Eui64Address & address)
{
uint8_t ad[8];
address.CopyTo (ad);
os.setf (std::ios::hex, std::ios::basefield);
std::cout.fill('0');
for (uint8_t i=0; i < 7; i++)
{
os << std::setw(2) << (uint32_t)ad[i] << ":";
}
// Final byte not suffixed by ":"
os << std::setw(2) << (uint32_t)ad[7];
os.setf (std::ios::dec, std::ios::basefield);
std::cout.fill(' ');
return os;
}
} // namespace ns3

98
src/node/eui64-address.h Normal file
View File

@@ -0,0 +1,98 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef EUI64_ADDRESS_H
#define EUI64_ADDRESS_H
#include <stdint.h>
#include <ostream>
namespace ns3 {
class Address;
/**
* \brief an EUI-64 address
*
* This class can contain 64 bit IEEE addresses.
*/
class Eui64Address
{
public:
Eui64Address ();
/**
* \param str a string representing the new Eui64Address
*
* The format of the string is "xx:xx:xx:xx:xx:xx"
*/
Eui64Address (const char *str);
/**
* \param buffer address in network order
*
* Copy the input address to our internal buffer.
*/
void CopyFrom (const uint8_t buffer[8]);
/**
* \param buffer address in network order
*
* Copy the internal address to the input buffer.
*/
void CopyTo (uint8_t buffer[8]) const;
/**
* \returns a new Address instance
*
* Convert an instance of this class to a polymorphic Address instance.
*/
operator Address ();
/**
* \param address a polymorphic address
* \returns a new Eui64Address from the polymorphic address
*
* This function performs a type check and asserts if the
* type of the input address is not compatible with an
* Eui64Address.
*/
static Eui64Address ConvertFrom (const Address &address);
/**
* \returns true if the address matches, false otherwise.
*/
static bool IsMatchingType (const Address &address);
/**
* Allocate a new Eui64Address.
*/
static Eui64Address Allocate (void);
private:
/**
* \returns a new Address instance
*
* Convert an instance of this class to a polymorphic Address instance.
*/
Address ConvertTo (void) const;
static uint8_t GetType (void);
uint8_t m_address[8];
};
bool operator == (const Eui64Address &a, const Eui64Address &b);
bool operator != (const Eui64Address &a, const Eui64Address &b);
std::ostream& operator<< (std::ostream& os, const Eui64Address & address);
} // namespace ns3
#endif /* EUI64_ADDRESS_H */

View File

@@ -0,0 +1,85 @@
#include "inet-socket-address.h"
#include "ns3/assert.h"
namespace ns3 {
InetSocketAddress::InetSocketAddress (Ipv4Address ipv4, uint16_t port)
: m_ipv4 (ipv4),
m_port (port)
{}
InetSocketAddress::InetSocketAddress (Ipv4Address ipv4)
: m_ipv4 (ipv4),
m_port (0)
{}
InetSocketAddress::InetSocketAddress (const char *ipv4, uint16_t port)
: m_ipv4 (Ipv4Address (ipv4)),
m_port (port)
{}
InetSocketAddress::InetSocketAddress (const char * ipv4)
: m_ipv4 (Ipv4Address (ipv4)),
m_port (0)
{}
InetSocketAddress::InetSocketAddress (uint16_t port)
: m_ipv4 (Ipv4Address::GetAny ()),
m_port (port)
{}
uint16_t
InetSocketAddress::GetPort (void) const
{
return m_port;
}
Ipv4Address
InetSocketAddress::GetIpv4 (void) const
{
return m_ipv4;
}
void
InetSocketAddress::SetPort (uint16_t port)
{
m_port = port;
}
void
InetSocketAddress::SetIpv4 (Ipv4Address address)
{
m_ipv4 = address;
}
bool
InetSocketAddress::IsMatchingType (const Address &address)
{
return address.CheckCompatible (GetType (), 6);
}
InetSocketAddress::operator Address () const
{
return ConvertTo ();
}
Address
InetSocketAddress::ConvertTo (void) const
{
uint8_t buf[6];
m_ipv4.Serialize (buf);
buf[4] = m_port & 0xff;
buf[5] = (m_port >> 8) & 0xff;
return Address (GetType (), buf, 6);
}
InetSocketAddress
InetSocketAddress::ConvertFrom (const Address &address)
{
NS_ASSERT (address.CheckCompatible (GetType (), 6));
uint8_t buf[6];
address.CopyTo (buf);
Ipv4Address ipv4 = Ipv4Address::Deserialize (buf);
uint16_t port = buf[0] | (buf[1] << 8);
return InetSocketAddress (ipv4, port);
}
uint8_t
InetSocketAddress::GetType (void)
{
static uint8_t type = Address::Register ();
return type;
}
} // namespace ns3

View File

@@ -0,0 +1,96 @@
#ifndef IPV4_TRANSPORT_ADDRESS_H
#define IPV4_TRANSPORT_ADDRESS_H
#include "address.h"
#include "ipv4-address.h"
#include <stdint.h>
namespace ns3 {
/**
* \brief an Inet address class
*
* This class is similar to inet_sockaddr in the BSD socket
* API. i.e., this class holds an Ipv4Address and a port number
* to form an ipv4 transport endpoint.
*/
class InetSocketAddress
{
public:
/**
* \param ipv4 the ipv4 address
* \param port the port number
*/
InetSocketAddress (Ipv4Address ipv4, uint16_t port);
/**
* \param ipv4 the ipv4 address
*
* The port number is set to zero by default.
*/
InetSocketAddress (Ipv4Address ipv4);
/**
* \param port the port number
*
* The ipv4 address is set to the "Any" address by default.
*/
InetSocketAddress (uint16_t port);
/**
* \param ipv4 string which represents an ipv4 address
* \param port the port number
*/
InetSocketAddress (const char *ipv4, uint16_t port);
/**
* \param ipv4 string which represents an ipv4 address
*
* The port number is set to zero.
*/
InetSocketAddress (const char *ipv4);
/**
* \returns the port number
*/
uint16_t GetPort (void) const;
/**
* \returns the ipv4 address
*/
Ipv4Address GetIpv4 (void) const;
/**
* \param port the new port number.
*/
void SetPort (uint16_t port);
/**
* \param address the new ipv4 address
*/
void SetIpv4 (Ipv4Address address);
/**
* \returns true if the address matches, false otherwise.
*/
static bool IsMatchingType (const Address &address);
/**
* \returns an Address instance which represents this
* InetSocketAddress instance.
*/
operator Address () const;
/**
* \param address the Address instance to convert from.
*
* Returns an InetSocketAddress which corresponds to the input
* Address
*/
static InetSocketAddress ConvertFrom (const Address &address);
private:
Address ConvertTo (void) const;
static uint8_t GetType (void);
Ipv4Address m_ipv4;
uint16_t m_port;
};
} // namespace ns3
#endif /* IPV4_TRANSPORT_ADDRESS_H */

View File

@@ -19,11 +19,11 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "ns3/debug.h"
#include "ipv4-address.h"
#include "ns3/assert.h"
NS_DEBUG_COMPONENT_DEFINE("Ipv4Address");
#include "ipv4-address.h"
namespace ns3 {
@@ -193,6 +193,20 @@ Ipv4Address::Serialize (uint8_t buf[4]) const
buf[2] = (m_address >> 8) & 0xff;
buf[3] = (m_address >> 0) & 0xff;
}
Ipv4Address
Ipv4Address::Deserialize (const uint8_t buf[4])
{
Ipv4Address ipv4;
ipv4.m_address = 0;
ipv4.m_address |= buf[0];
ipv4.m_address <<= 8;
ipv4.m_address |= buf[1];
ipv4.m_address <<= 8;
ipv4.m_address |= buf[2];
ipv4.m_address <<= 8;
ipv4.m_address |= buf[3];
return ipv4;
}
void
Ipv4Address::Print (std::ostream &os) const
@@ -203,7 +217,39 @@ Ipv4Address::Print (std::ostream &os) const
<< ((m_address >> 0) & 0xff);
}
bool
Ipv4Address::IsMatchingType (const Address &address)
{
return address.CheckCompatible (GetType (), 4);
}
Ipv4Address::operator Address ()
{
return ConvertTo ();
}
Address
Ipv4Address::ConvertTo (void) const
{
uint8_t buf[4];
Serialize (buf);
return Address (GetType (), buf, 4);
}
Ipv4Address
Ipv4Address::ConvertFrom (const Address &address)
{
NS_ASSERT (address.CheckCompatible (GetType (), 4));
uint8_t buf[4];
address.CopyTo (buf);
return Deserialize (buf);
}
uint8_t
Ipv4Address::GetType (void)
{
static uint8_t type = Address::Register ();
return type;
}
Ipv4Address
Ipv4Address::GetZero (void)

View File

@@ -24,6 +24,7 @@
#include <stdint.h>
#include <ostream>
#include "address.h"
namespace ns3 {
@@ -86,10 +87,18 @@ public:
void SetHostOrder (uint32_t ip);
/**
* Serialize this address to a 4-byte buffer
*
* \param buf output buffer to which this address gets overwritten with this
* Ipv4Address
*/
void Serialize (uint8_t buf[4]) const;
/**
* \param buf buffer to read address from
* \returns an Ipv4Address
*
* The input address is expected to be in network byte order format.
*/
static Ipv4Address Deserialize (const uint8_t buf[4]);
/**
* \brief Print this address to the given output stream
*
@@ -111,11 +120,17 @@ public:
*/
Ipv4Address CombineMask (Ipv4Mask const &mask) const;
static bool IsMatchingType (const Address &address);
operator Address ();
static Ipv4Address ConvertFrom (const Address &address);
static Ipv4Address GetZero (void);
static Ipv4Address GetAny (void);
static Ipv4Address GetBroadcast (void);
static Ipv4Address GetLoopback (void);
private:
Address ConvertTo (void) const;
static uint8_t GetType (void);
uint32_t m_address;
};

View File

@@ -1,210 +0,0 @@
/* -*- 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include <iostream>
#include <iomanip>
#include "ns3/assert.h"
#include "mac-address.h"
#define ASCII_a (0x41)
#define ASCII_z (0x5a)
#define ASCII_A (0x61)
#define ASCII_Z (0x7a)
#define ASCII_COLON (0x3a)
#define ASCII_ZERO (0x30)
namespace ns3 {
// Static variables
uint8_t MacAddress::g_nextAddress[MacAddress::MAX_LEN];
static char
AsciiToLowCase (char c)
{
if (c >= ASCII_a && c <= ASCII_z) {
return c;
} else if (c >= ASCII_A && c <= ASCII_Z) {
return c + (ASCII_a - ASCII_A);
} else {
return c;
}
}
MacAddress::MacAddress () : m_len(0)
{
for (int i=0; i < MacAddress::MAX_LEN; i++)
{
m_address[i] = 0;
}
}
MacAddress::MacAddress(uint8_t len) : m_len(len)
{
NS_ASSERT (len <= MacAddress::MAX_LEN);
AdvanceAddress();
memcpy(m_address, g_nextAddress, len);
}
MacAddress::MacAddress (uint8_t const *address, uint8_t len)
{
NS_ASSERT (len <= MacAddress::MAX_LEN);
for (int i=0; i < len; i++)
{
m_address[i] = address[i];
}
for (int i=len; i < MacAddress::MAX_LEN; i++)
{
m_address[i] = 0;
}
m_len = len;
}
MacAddress::MacAddress (char const *str)
{
int i = 0;
while (*str != 0 && i < MacAddress::MAX_LEN) {
uint8_t byte = 0;
while (*str != ASCII_COLON && *str != 0) {
byte <<= 4;
char low = AsciiToLowCase (*str);
if (low >= ASCII_a) {
byte |= low - ASCII_a + 10;
} else {
byte |= low - ASCII_ZERO;
}
str++;
}
m_address[i] = byte;
i++;
if (*str == 0) {
break;
}
str++;
}
m_len = i;
}
MacAddress::~MacAddress ()
{}
bool
MacAddress::IsEqual (MacAddress other) const
{
if (memcmp(other.m_address, m_address, m_len))
{
return false;
}
else
{
return true;
}
}
void
MacAddress::Print (std::ostream &os) const
{
int i;
if (m_len == 0)
{
os << "NULL-ADDRESS";
return;
}
os.setf (std::ios::hex, std::ios::basefield);
std::cout.fill('0');
for (i=0; i< (m_len-1); i++)
{
os << std::setw(2) << (uint32_t)m_address[i] << ":";
}
// Final byte not suffixed by ":"
os << std::setw(2) << (uint32_t)m_address[i];
os.setf (std::ios::dec, std::ios::basefield);
std::cout.fill(' ');
}
uint8_t
MacAddress::GetLength () const
{
return m_len;
}
void
MacAddress::Peek (uint8_t ad[MacAddress::MAX_LEN]) const
{
memcpy (ad, m_address, MacAddress::MAX_LEN);
}
void
MacAddress::Set (uint8_t const ad[MacAddress::MAX_LEN], uint8_t len)
{
memcpy (m_address, ad, MacAddress::MAX_LEN);
m_len = len;
}
// Static methods
void MacAddress::AdvanceAddress()
{
// Advance to next address, little end first
for(size_t i = 0; i < MAX_LEN; ++i)
{
if (++g_nextAddress[i] != 0) break;
}
}
// Non-member operators
bool operator == (MacAddress const&a, MacAddress const&b)
{
return a.IsEqual (b);
}
bool operator != (MacAddress const&a, MacAddress const&b)
{
return !a.IsEqual (b);
}
bool operator < (MacAddress const&a, MacAddress const&b)
{
uint8_t a_p[MacAddress::MAX_LEN];
uint8_t b_p[MacAddress::MAX_LEN];
a.Peek (a_p);
b.Peek (b_p);
NS_ASSERT (a.GetLength() == b.GetLength());
for (uint8_t i = 0; i < a.GetLength(); i++)
{
if (a_p[i] < b_p[i])
{
return true;
}
else if (a_p[i] > b_p[i])
{
return false;
}
}
return false;
}
std::ostream& operator<< (std::ostream& os, MacAddress const& address)
{
address.Print (os);
return os;
}
}; // namespace ns3

View File

@@ -1,128 +0,0 @@
/* -*- 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef MAC_ADDRESS_H
#define MAC_ADDRESS_H
#include <stdint.h>
#include <ostream>
namespace ns3 {
/**
* \brief base class for Network Device addresses
*
* This class is a base class for different types of Network
* Device addresses. It generically stores an address of
* MAX_ADDR_LEN bytes, and provides methods to compare, print, and set
* the address.
*/
class MacAddress {
public:
enum {
MAX_LEN = 32
};
/**
* \brief Construct a null MacAddress
*
* This MacAddress has length of zero, and is internally all zeros
*/
MacAddress (void);
/**
* \brief Construct a MacAddress using the next available
* address.
* \see MacAddres::Next
* \param len length, in bytes, of the desired address
*/
MacAddress(uint8_t len);
/**
* \brief Construct a MacAddress from a byte-array
*
* low byte should be first.
* \param address a byte array indicating the address
* \param len length, in bytes, of the address points to
*/
MacAddress (uint8_t const *address, uint8_t len);
/**
* \brief Construct a MacAddress from a C-string
*
* The string should look like this:
* hh:xx:xx:xx:xx:ll
* where hh is the high byte and ll is
* the low byte.
* \param address the C-string representation of the address
*/
MacAddress (char const *address);
~MacAddress ();
/**
* \brief Comparison operation between MacAddresses
* \param other The address against which to compare this one
* \return True if they are equal, false otherwise.
*/
bool IsEqual (MacAddress other) const;
/**
* \brief Print this MacAddress to a stream
*
* The format is colon seperated groups of two hexadecimal digits
* \param os The output stream desired
*/
void Print (std::ostream &os) const;
/**
* \return The length in bytes of this MacAddress
*/
uint8_t GetLength() const;
/**
* \brief Copy routine to peek the contents of the MacAddress
*
* \param ad Output parameter which holds a copy of this MacAddress
*/
void Peek (uint8_t ad[MAX_LEN]) const;
/**
* \brief Sets this MacAddress to a specific value
* \param ad byte buffer to set the MacAddress to
* \param len the length of the buffer
*/
void Set (uint8_t const ad[MAX_LEN], uint8_t len);
// Static methods/members
/**
*
* Advance the global to the next available mac address.
*/
static void AdvanceAddress();
static uint8_t g_nextAddress[MAX_LEN];
private:
uint8_t m_address[MAX_LEN];
uint8_t m_len;
};
bool operator == (MacAddress const&a, MacAddress const&b);
bool operator != (MacAddress const&a, MacAddress const&b);
bool operator < (MacAddress const&a, MacAddress const&b);
std::ostream& operator<< (std::ostream& os, MacAddress const& address);
}; // namespace ns3
#endif /* MAC_ADDRESS_H */

View File

@@ -35,7 +35,7 @@ namespace ns3 {
const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid);
NetDevice::NetDevice(Ptr<Node> node, const MacAddress& addr) :
NetDevice::NetDevice(Ptr<Node> node, const Address& addr) :
m_node (node),
m_name(""),
m_ifIndex (0),
@@ -53,7 +53,7 @@ NetDevice::NetDevice(Ptr<Node> node, const MacAddress& addr) :
NetDevice::~NetDevice ()
{}
MacAddress
Address
NetDevice::GetAddress (void) const
{
return m_address;
@@ -113,7 +113,7 @@ NetDevice::IsBroadcast (void) const
{
return m_isBroadcast;
}
MacAddress const &
Address const &
NetDevice::GetBroadcast (void) const
{
NS_ASSERT (m_isBroadcast);
@@ -121,7 +121,7 @@ NetDevice::GetBroadcast (void) const
}
void
NetDevice::EnableBroadcast (MacAddress broadcast)
NetDevice::EnableBroadcast (Address broadcast)
{
m_isBroadcast = true;
m_broadcast = broadcast;
@@ -171,7 +171,7 @@ NetDevice::DisablePointToPoint (void)
// Receive packet from above
bool
NetDevice::Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber)
NetDevice::Send(Packet& p, const Address& dest, uint16_t protocolNumber)
{
if (m_isUp)
{
@@ -197,18 +197,19 @@ NetDevice::GetChannel (void) const
// Receive packets from below
bool
NetDevice::ForwardUp(Packet& p, uint32_t param)
NetDevice::ForwardUp(const Packet& p, uint32_t param, const Address &from)
{
bool retval = false;
Packet packet = p;
NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid()
NS_DEBUG ("NetDevice::ForwardUp: UID is " << p.GetUid()
<< " device is: " << GetName());
if (!m_receiveCallback.IsNull ())
{
retval = m_receiveCallback (this, packet, param);
} else {
retval = m_receiveCallback (this, p, param, from);
}
else
{
NS_DEBUG ("NetDevice::Receive call back is NULL");
}
@@ -248,7 +249,7 @@ NetDevice::NeedsArp (void) const
}
void
NetDevice::SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb)
NetDevice::SetReceiveCallback (ReceiveCallback cb)
{
m_receiveCallback = cb;
}

View File

@@ -28,7 +28,7 @@
#include "ns3/packet.h"
#include "ns3/object.h"
#include "ns3/ptr.h"
#include "mac-address.h"
#include "address.h"
namespace ns3 {
@@ -79,9 +79,9 @@ public:
Ptr<Channel> GetChannel (void) const;
/**
* \return the current MacAddress of this interface.
* \return the current Address of this interface.
*/
MacAddress GetAddress (void) const;
Address GetAddress (void) const;
/**
* \param mtu MTU value, in bytes, to set for the device
* \return whether the MTU value was within legal bounds
@@ -137,7 +137,7 @@ public:
* Calling this method is invalid if IsBroadcast returns
* not true.
*/
MacAddress const &GetBroadcast (void) const;
Address const &GetBroadcast (void) const;
/**
* \return value of m_isMulticast flag
*/
@@ -154,11 +154,11 @@ public:
* is received.
*
* Called from higher layer to send packet into Network Device
* to the specified destination MacAddress
* to the specified destination Address
*
* \return whether the Send operation succeeded
*/
bool Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber);
bool Send(Packet& p, const Address& dest, uint16_t protocolNumber);
/**
* \returns the node base class which contains this network
* interface.
@@ -177,23 +177,36 @@ public:
*/
bool NeedsArp (void) const;
/**
* \param device a pointer to the net device which is calling this callback
* \param packet the packet received
* \param protocol the 16 bit protocol number associated with this packet.
* This protocol number is expected to be the same protocol number
* given to the Send method by the user on the sender side.
* \param address the address of the sender
* \returns true if the callback could handle the packet successfully, false
* otherwise.
*/
typedef Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t,const Address &> ReceiveCallback;
/**
* \param cb callback to invoke whenever a packet has been received and must
* be forwarded to the higher layers.
*
*/
void SetReceiveCallback (Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> cb);
void SetReceiveCallback (ReceiveCallback cb);
protected:
/**
* \param node base class node pointer of device's node
* \param addr MAC address of this device.
*/
NetDevice(Ptr<Node> node, const MacAddress& addr);
NetDevice(Ptr<Node> node, const Address& addr);
/**
* Enable broadcast support. This method should be
* called by subclasses from their constructor
*/
void EnableBroadcast (MacAddress broadcast);
void EnableBroadcast (Address broadcast);
/**
* Set m_isBroadcast flag to false
*/
@@ -230,6 +243,7 @@ public:
* \param p packet sent from below up to Network Device
* \param param Extra parameter extracted from header and needed by
* some protocols
* \param address the address of the sender of this packet.
* \returns true if the packet was forwarded successfully,
* false otherwise.
*
@@ -237,7 +251,7 @@ 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, uint32_t param);
bool ForwardUp (const Packet& p, uint32_t param, const Address &address);
/**
@@ -248,8 +262,6 @@ public:
*/
virtual void DoDispose (void);
Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
private:
/**
* \param p packet to send
@@ -262,7 +274,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, uint16_t protocolNumber) = 0;
virtual bool SendTo (Packet& p, const Address &dest, uint16_t protocolNumber) = 0;
/**
* \returns true if this NetDevice needs the higher-layers
* to perform ARP over it, false otherwise.
@@ -289,14 +301,15 @@ public:
Ptr<Node> m_node;
std::string m_name;
uint16_t m_ifIndex;
MacAddress m_address;
MacAddress m_broadcast;
Address m_address;
Address m_broadcast;
uint16_t m_mtu;
bool m_isUp;
bool m_isBroadcast;
bool m_isMulticast;
bool m_isPointToPoint;
Callback<void> m_linkChangeCallback;
ReceiveCallback m_receiveCallback;
};
}; // namespace ns3

View File

@@ -77,7 +77,6 @@ public:
NodeList::Iterator Begin (void);
NodeList::Iterator End (void);
TraceResolver *CreateTraceResolver (TraceContext const &context);
Node *PeekNode (uint32_t n);
Ptr<Node> GetNode (uint32_t n);
uint32_t GetNNodes (void);
@@ -123,11 +122,6 @@ NodeListPriv::GetNNodes (void)
{
return m_nodes.size ();
}
Node *
NodeListPriv::PeekNode (uint32_t n)
{
return PeekPointer (m_nodes[n]);
}
Ptr<Node>
NodeListPriv::GetNode (uint32_t n)
@@ -139,11 +133,11 @@ NodeListPriv::GetNode (uint32_t n)
TraceResolver *
NodeListPriv::CreateTraceResolver (TraceContext const &context)
{
ArrayTraceResolver<Node, NodeListIndex> *resolver =
new ArrayTraceResolver<Node, NodeListIndex>
ArrayTraceResolver<Ptr<Node>, NodeListIndex> *resolver =
new ArrayTraceResolver<Ptr<Node>, NodeListIndex>
(context,
MakeCallback (&NodeListPriv::GetNNodes, this),
MakeCallback (&NodeListPriv::PeekNode, this));
MakeCallback (&NodeListPriv::GetNode, this));
return resolver;
}

View File

@@ -1,32 +1,30 @@
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// 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: George F. Riley<riley@ece.gatech.edu>
//
// Implement the basic Node object for ns3.
// George F. Riley, Georgia Tech, Fall 2006
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
*
* 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
*
* Authors: George F. Riley<riley@ece.gatech.edu>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "node.h"
#include "node-list.h"
#include "net-device.h"
#include "application.h"
#include "packet-socket-factory.h"
#include "ns3/simulator.h"
#include "ns3/composite-trace-resolver.h"
namespace ns3{
@@ -36,16 +34,23 @@ Node::Node()
: m_id(0),
m_sid(0)
{
SetInterfaceId (Node::iid);
m_id = NodeList::Add (this);
Construct ();
}
Node::Node(uint32_t sid)
: m_id(0),
m_sid(sid)
{
Construct ();
}
void
Node::Construct (void)
{
SetInterfaceId (Node::iid);
m_id = NodeList::Add (this);
Ptr<PacketSocketFactory> socketFactory = Create<PacketSocketFactory> ();
AddInterface (socketFactory);
}
Node::~Node ()
@@ -54,7 +59,9 @@ Node::~Node ()
TraceResolver *
Node::CreateTraceResolver (TraceContext const &context)
{
return DoCreateTraceResolver (context);
CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
DoFillTraceResolver (*resolver);
return resolver;
}
uint32_t
@@ -74,8 +81,9 @@ Node::AddDevice (Ptr<NetDevice> device)
{
uint32_t index = m_devices.size ();
m_devices.push_back (device);
DoAddDevice (device);
device->SetIfIndex(index);
device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this));
NotifyDeviceAdded (device);
return index;
}
Ptr<NetDevice>
@@ -107,8 +115,27 @@ Node::GetNApplications (void) const
return m_applications.size ();
}
TraceResolver *
Node::CreateDevicesTraceResolver (const TraceContext &context)
{
ArrayTraceResolver<Ptr<NetDevice> > *resolver =
new ArrayTraceResolver<Ptr<NetDevice> > (context,
MakeCallback (&Node::GetNDevices, this),
MakeCallback (&Node::GetDevice, this));
return resolver;
}
void Node::DoDispose()
void
Node::DoFillTraceResolver (CompositeTraceResolver &resolver)
{
resolver.Add ("devices",
MakeCallback (&Node::CreateDevicesTraceResolver, this),
Node::DEVICES);
}
void
Node::DoDispose()
{
for (std::vector<Ptr<NetDevice> >::iterator i = m_devices.begin ();
i != m_devices.end (); i++)
@@ -129,4 +156,56 @@ void Node::DoDispose()
Object::DoDispose ();
}
void
Node::NotifyDeviceAdded (Ptr<NetDevice> device)
{}
void
Node::RegisterProtocolHandler (ProtocolHandler handler,
uint16_t protocolType,
Ptr<NetDevice> device)
{
struct Node::ProtocolHandlerEntry entry;
entry.handler = handler;
entry.protocol = protocolType;
entry.device = device;
m_handlers.push_back (entry);
}
void
Node::UnregisterProtocolHandler (ProtocolHandler handler)
{
for (ProtocolHandlerList::iterator i = m_handlers.begin ();
i != m_handlers.end (); i++)
{
if (i->handler.IsEqual (handler))
{
m_handlers.erase (i);
break;
}
}
}
bool
Node::ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet,
uint16_t protocol, const Address &from)
{
bool found = false;
for (ProtocolHandlerList::iterator i = m_handlers.begin ();
i != m_handlers.end (); i++)
{
if (i->device == 0 ||
(i->device != 0 && i->device == device))
{
if (i->protocol == 0 ||
i->protocol == protocol)
{
i->handler (device, packet, protocol, from);
found = true;
}
}
}
return found;
}
}//namespace ns3

View File

@@ -1,33 +1,31 @@
// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
//
// Copyright (c) 2006 Georgia Tech Research Corporation
// 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: George F. Riley<riley@ece.gatech.edu>
//
// Define the basic Node object for ns3.
// George F. Riley, Georgia Tech, Fall 2006
#ifndef I_NODE_H
#define I_NODE_H
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
*
* 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
*
* Authors: George F. Riley<riley@ece.gatech.edu>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef NODE_H
#define NODE_H
#include <vector>
#include "ns3/object.h"
#include "ns3/callback.h"
#include "ns3/array-trace-resolver.h"
namespace ns3 {
@@ -35,6 +33,9 @@ class TraceContext;
class TraceResolver;
class NetDevice;
class Application;
class Packet;
class Address;
class CompositeTraceResolver;
/**
* \brief A network Node.
@@ -57,6 +58,18 @@ class Node : public Object
{
public:
static const InterfaceId iid;
typedef ArrayTraceResolver<Ptr<NetDevice> >::Index NetDeviceIndex;
/**
* Must be invoked by subclasses only.
*/
Node();
/**
* \param systemId a unique integer used for parallel simulations.
*
* Must be invoked by subclasses only.
*/
Node(uint32_t systemId);
virtual ~Node();
@@ -93,11 +106,15 @@ public:
* Associate this device to this node.
* This method is called automatically from NetDevice::NetDevice
* so the user has little reason to call this method himself.
* The index returned is always non-zero.
*/
uint32_t AddDevice (Ptr<NetDevice> device);
/**
* \param index the index of the requested NetDevice
* \returns the requested NetDevice associated to this Node.
*
* The indexes used by the GetDevice method start at one and
* end at GetNDevices ()
*/
Ptr<NetDevice> GetDevice (uint32_t index) const;
/**
@@ -127,31 +144,51 @@ public:
*/
uint32_t GetNApplications (void) const;
protected:
/**
* Must be invoked by subclasses only.
* A protocol handler
*/
Node();
typedef Callback<void,Ptr<NetDevice>, const Packet &,uint16_t,const Address &> ProtocolHandler;
/**
* \param systemId a unique integer used for parallel simulations.
* \param handler the handler to register
* \param protocolType the type of protocol this handler is
* interested in. This protocol type is a so-called
* EtherType, as registered here:
* http://standards.ieee.org/regauth/ethertype/eth.txt
* the value zero is interpreted as matching all
* protocols.
* \param device the device attached to this handler. If the
* value is zero, the handler is attached to all
* devices on this node.
*/
void RegisterProtocolHandler (ProtocolHandler handler,
uint16_t protocolType,
Ptr<NetDevice> device);
/**
* \param handler the handler to unregister
*
* Must be invoked by subclasses only.
* After this call returns, the input handler will never
* be invoked anymore.
*/
Node(uint32_t systemId);
void UnregisterProtocolHandler (ProtocolHandler handler);
protected:
/**
* The dispose method. Subclasses must override this method
* and must chain up to it by calling Node::DoDispose at the
* end of their own DoDispose method.
*/
virtual void DoDispose (void);
private:
/**
* \param context the trace context
* \returns a trace resolver to the user. The user must delete it.
* \param resolver the resolver to store trace sources in.
*
* Subclasses must implement this method.
* If a subclass wants to add new traces to a Node, it needs
* to override this method and record the new trace sources
* in the input resolver. Subclasses also _must_ chain up to
* their parent's DoFillTraceResolver method prior
* to recording they own trace sources.
*/
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
virtual void DoFillTraceResolver (CompositeTraceResolver &resolver);
private:
/**
* \param device the device added to this Node.
*
@@ -160,14 +197,29 @@ private:
* at this point to setup the node's receive function for
* the NetDevice packets.
*/
virtual void DoAddDevice (Ptr<NetDevice> device) = 0;
virtual void NotifyDeviceAdded (Ptr<NetDevice> device);
bool ReceiveFromDevice (Ptr<NetDevice> device, const Packet &packet,
uint16_t protocol, const Address &from);
void Construct (void);
TraceResolver *CreateDevicesTraceResolver (const TraceContext &context);
enum TraceSource {
DEVICES
};
struct ProtocolHandlerEntry {
ProtocolHandler handler;
uint16_t protocol;
Ptr<NetDevice> device;
};
typedef std::vector<struct Node::ProtocolHandlerEntry> ProtocolHandlerList;
uint32_t m_id; // Node id for this node
uint32_t m_sid; // System id for this node
std::vector<Ptr<NetDevice> > m_devices;
std::vector<Ptr<Application> > m_applications;
ProtocolHandlerList m_handlers;
};
} //namespace ns3
#endif /* I_NODE_H */
#endif /* NODE_H */

View File

@@ -0,0 +1,134 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "packet-socket-address.h"
#include "net-device.h"
namespace ns3 {
PacketSocketAddress::PacketSocketAddress ()
{}
void
PacketSocketAddress::SetProtocol (uint16_t protocol)
{
m_protocol = protocol;
}
void
PacketSocketAddress::SetAllDevices (void)
{
m_isSingleDevice = false;
m_device = 0;
}
void
PacketSocketAddress::SetSingleDevice (uint32_t index)
{
m_isSingleDevice = true;
m_device = index;
}
void
PacketSocketAddress::SetPhysicalAddress (const Address address)
{
m_address = address;
}
uint16_t
PacketSocketAddress::GetProtocol (void) const
{
return m_protocol;
}
bool
PacketSocketAddress::IsSingleDevice (void) const
{
return m_isSingleDevice;
}
uint32_t
PacketSocketAddress::GetSingleDevice (void) const
{
return m_device;
}
Address
PacketSocketAddress::GetPhysicalAddress (void) const
{
return m_address;
}
PacketSocketAddress::operator Address () const
{
return ConvertTo ();
}
Address
PacketSocketAddress::ConvertTo (void) const
{
Address address;
uint8_t buffer[Address::MAX_SIZE];
buffer[0] = m_protocol & 0xff;
buffer[1] = (m_protocol >> 8) & 0xff;
buffer[2] = (m_device >> 24) & 0xff;
buffer[3] = (m_device >> 16) & 0xff;
buffer[4] = (m_device >> 8) & 0xff;
buffer[5] = (m_device >> 0) & 0xff;
buffer[6] = m_isSingleDevice?1:0;
uint32_t copied = m_address.CopyAllTo (buffer + 7, Address::MAX_SIZE - 7);
return Address (GetType (), buffer, 7 + copied);
}
PacketSocketAddress
PacketSocketAddress::ConvertFrom (const Address &address)
{
NS_ASSERT (IsMatchingType (address));
uint8_t buffer[Address::MAX_SIZE];
address.CopyTo (buffer);
uint16_t protocol = buffer[0] | (buffer[1] << 8);
uint32_t device = 0;
device |= buffer[2];
device <<= 8;
device |= buffer[3];
device <<= 8;
device |= buffer[4];
device <<= 8;
device |= buffer[5];
bool isSingleDevice = (buffer[6] == 1)?true:false;
Address physical;
physical.CopyAllFrom (buffer + 7, Address::MAX_SIZE - 7);
PacketSocketAddress ad;
ad.SetProtocol (protocol);
if (isSingleDevice)
{
ad.SetSingleDevice (device);
}
else
{
ad.SetAllDevices ();
}
ad.SetPhysicalAddress (physical);
return ad;
}
bool
PacketSocketAddress::IsMatchingType (const Address &address)
{
return address.IsMatchingType (GetType ());
}
uint8_t
PacketSocketAddress::GetType (void)
{
static uint8_t type = Address::Register ();
return type;
}
} // namespace ns3

View File

@@ -0,0 +1,77 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
*
* 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef PACKET_SOCKET_ADDRESS_H
#define PACKET_SOCKET_ADDRESS_H
#include "ns3/ptr.h"
#include "address.h"
#include "eui48-address.h"
#include "eui64-address.h"
#include "net-device.h"
namespace ns3 {
class NetDevice;
class PacketSocketAddress
{
public:
PacketSocketAddress ();
void SetProtocol (uint16_t protocol);
void SetAllDevices (void);
void SetSingleDevice (uint32_t device);
void SetPhysicalAddress (const Address address);
uint16_t GetProtocol (void) const;
uint32_t GetSingleDevice (void) const;
bool IsSingleDevice (void) const;
Address GetPhysicalAddress (void) const;
/**
* \returns a new Address instance
*
* Convert an instance of this class to a polymorphic Address instance.
*/
operator Address () const;
/**
* \param address a polymorphic address
*
* Convert a polymorphic address to an Eui48Address instance.
* The conversion performs a type check.
*/
static PacketSocketAddress ConvertFrom (const Address &address);
/**
* \returns true if the address matches, false otherwise.
*/
static bool IsMatchingType (const Address &address);
private:
static uint8_t GetType (void);
Address ConvertTo (void) const;
uint16_t m_protocol;
bool m_isSingleDevice;
uint32_t m_device;
Address m_address;
};
} // namespace ns3
#endif /* PACKET_SOCKET_ADDRESS_H */

View File

@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
* Copyright (c) 2007 Emmanuelle Laprise
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -16,36 +16,25 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#ifndef ARP_PRIVATE_H
#define ARP_PRIVATE_H
#include "ns3/object.h"
#include "ns3/ipv4-address.h"
#include "packet-socket-factory.h"
#include "node.h"
namespace ns3 {
class NetDevice;
class MacAddress;
class Packet;
class ArpL3Protocol;
const InterfaceId PacketSocketFactory::iid = MakeInterfaceId ("Packet",
SocketFactory::iid);
class ArpPrivate : public Object
PacketSocketFactory::PacketSocketFactory ()
{
public:
static const InterfaceId iid;
ArpPrivate (Ptr<ArpL3Protocol> arp);
virtual ~ArpPrivate ();
bool Lookup (Packet &p, Ipv4Address destination,
Ptr<NetDevice> device,
MacAddress *hardwareDestination);
protected:
virtual void DoDispose (void);
private:
Ptr<ArpL3Protocol> m_arp;
};
SetInterfaceId (PacketSocketFactory::iid);
}
Ptr<Socket> PacketSocketFactory::CreateSocket (void)
{
Ptr<Node> node = QueryInterface<Node> (Node::iid);
Ptr<PacketSocket> socket = Create<PacketSocket> (node);
return socket;
}
} // namespace ns3
#endif /* ARP_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 INRIA
* Copyright (c) 2007 Emmanuelle Laprise
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -16,41 +16,37 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include "arp-private.h"
#include "arp-l3-protocol.h"
#include "ns3/assert.h"
#include "ns3/net-device.h"
#ifndef PACKET_SOCKET_FACTORY_H
#define PACKET_SOCKET_FACTORY_H
#include "socket-factory.h"
#include "packet-socket.h"
namespace ns3 {
const InterfaceId ArpPrivate::iid = MakeInterfaceId ("ArpPrivate", Object::iid);
class Socket;
ArpPrivate::ArpPrivate (Ptr<ArpL3Protocol> arp)
: m_arp (arp)
/**
* This can be used as an interface in a node in order for the node to
* generate PacketSockets that can connect to net devices.
*/
class PacketSocketFactory : public SocketFactory
{
SetInterfaceId (ArpPrivate::iid);
}
ArpPrivate::~ArpPrivate ()
{
NS_ASSERT (m_arp == 0);
}
public:
static const InterfaceId iid; /// Interface identifier
bool
ArpPrivate::Lookup (Packet &p, Ipv4Address destination,
Ptr<NetDevice> device,
MacAddress *hardwareDestination)
{
return m_arp->Lookup (p, destination, device, hardwareDestination);
}
void
ArpPrivate::DoDispose (void)
{
m_arp = 0;
Object::DoDispose ();
}
PacketSocketFactory ();
/**
* Creates a PacketSocket and returns a pointer to it.
*
* \return a pointer to the created socket
*/
virtual Ptr<Socket> CreateSocket (void);
};
} // namespace ns3
#endif /* PACKET_SOCKET_FACTORY_H */

341
src/node/packet-socket.cc Normal file
View File

@@ -0,0 +1,341 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise, INRIA
*
* 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
*
* Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#include "packet-socket.h"
#include "packet-socket-address.h"
#include "ns3/debug.h"
#include "ns3/node.h"
NS_DEBUG_COMPONENT_DEFINE ("PacketSocket");
namespace ns3 {
PacketSocket::PacketSocket (Ptr<Node> node)
: m_node (node)
{
Init();
}
void
PacketSocket::Init()
{
m_state = STATE_OPEN;
m_shutdownSend = false;
m_shutdownRecv = false;
m_errno = ERROR_NOTERROR;
}
PacketSocket::~PacketSocket ()
{}
void
PacketSocket::DoDispose (void)
{
m_device = 0;
}
Ptr<Node>
PacketSocket::GetNode (void) const
{
return m_node;
}
int
PacketSocket::Bind (void)
{
PacketSocketAddress address;
address.SetProtocol (0);
address.SetAllDevices ();
return DoBind (address);
}
int
PacketSocket::Bind (const Address &address)
{
if (!PacketSocketAddress::IsMatchingType (address))
{
m_errno = ERROR_INVAL;
return -1;
}
PacketSocketAddress ad = PacketSocketAddress::ConvertFrom (address);
return DoBind (ad);
}
int
PacketSocket::DoBind (const PacketSocketAddress &address)
{
if (m_state == STATE_BOUND ||
m_state == STATE_CONNECTED)
{
m_errno = ERROR_INVAL;
return -1;
}
if (m_state == STATE_CLOSED)
{
m_errno = ERROR_BADF;
return -1;
}
Ptr<NetDevice> dev ;
if (address.IsSingleDevice ())
{
dev = 0;
}
else
{
m_node->GetDevice (address.GetSingleDevice ());
}
m_node->RegisterProtocolHandler (MakeCallback (&PacketSocket::ForwardUp, this),
address.GetProtocol (), dev);
m_state = STATE_BOUND;
m_protocol = address.GetProtocol ();
m_isSingleDevice = address.IsSingleDevice ();
m_device = address.GetSingleDevice ();
return 0;
}
enum Socket::SocketErrno
PacketSocket::GetErrno (void) const
{
return m_errno;
}
int
PacketSocket::ShutdownSend (void)
{
if (m_state == STATE_CLOSED)
{
m_errno = ERROR_BADF;
return -1;
}
m_shutdownSend = true;
return 0;
}
int
PacketSocket::ShutdownRecv (void)
{
if (m_state == STATE_CLOSED)
{
m_errno = ERROR_BADF;
return -1;
}
m_shutdownRecv = false;
return 0;
}
int
PacketSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
{
if (m_state == STATE_CLOSED)
{
m_errno = ERROR_BADF;
return -1;
}
if (!closeCompleted.IsNull ())
{
closeCompleted (this);
}
m_state = STATE_CLOSED;
return 0;
}
int
PacketSocket::DoConnect(const Address &ad,
ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
ns3::Callback<void, Ptr<Socket> > connectionFailed,
ns3::Callback<void, Ptr<Socket> > halfClose)
{
PacketSocketAddress address;
if (m_state == STATE_CLOSED)
{
m_errno = ERROR_BADF;
goto error;
}
if (m_state == STATE_OPEN)
{
// connect should happen _after_ bind.
m_errno = ERROR_INVAL; // generic error condition.
goto error;
}
if (m_state == STATE_CONNECTED)
{
m_errno = ERROR_ISCONN;
goto error;
}
if (!PacketSocketAddress::IsMatchingType (ad))
{
m_errno = ERROR_AFNOSUPPORT;
goto error;
}
m_destAddr = ad;
m_state = STATE_CONNECTED;
if (!connectionSucceeded.IsNull ())
{
connectionSucceeded (this);
}
return 0;
error:
if (!connectionFailed.IsNull ())
{
connectionFailed (this);
}
return -1;
}
int
PacketSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
ns3::Callback<void, Ptr<Socket>, const Address &> newConnectionCreated,
ns3::Callback<void, Ptr<Socket> > closeRequested)
{
// calling accept on a packet socket is a programming error.
m_errno = ERROR_OPNOTSUPP;
return -1;
}
int
PacketSocket::DoSend (const uint8_t* buffer,
uint32_t size,
ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
if (m_state == STATE_OPEN ||
m_state == STATE_BOUND)
{
m_errno = ERROR_NOTCONN;
return -1;
}
return DoSendTo (m_destAddr, buffer, size, dataSent);
}
int
PacketSocket::DoSendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
PacketSocketAddress ad;
if (m_state == STATE_CLOSED)
{
m_errno = ERROR_BADF;
return -1;
}
if (m_state == STATE_OPEN)
{
// XXX should return another error here.
m_errno = ERROR_INVAL;
return -1;
}
if (m_shutdownSend)
{
m_errno = ERROR_SHUTDOWN;
return -1;
}
if (!PacketSocketAddress::IsMatchingType (address))
{
m_errno = ERROR_AFNOSUPPORT;
return -1;
}
ad = PacketSocketAddress::ConvertFrom (address);
Packet p;
if (buffer == 0)
{
p = Packet (size);
}
else
{
p = Packet (buffer, size);
}
bool error = false;
Address dest = ad.GetPhysicalAddress ();
if (ad.IsSingleDevice ())
{
Ptr<NetDevice> device = m_node->GetDevice (ad.GetSingleDevice ());
if (!device->Send (p, dest, ad.GetProtocol ()))
{
error = true;
}
}
else
{
for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
{
Ptr<NetDevice> device = m_node->GetDevice (i);
if (!device->Send (p, dest, ad.GetProtocol ()))
{
error = true;
}
}
}
if (!error && !dataSent.IsNull ())
{
dataSent (this, p.GetSize ());
}
if (error)
{
m_errno = ERROR_INVAL;
return -1;
}
else
{
return 0;
}
}
void
PacketSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address &> callback)
{
m_rxCallback = callback;
}
void
PacketSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t, const Address &> callback)
{
m_dummyRxCallback = callback;
}
void
PacketSocket::ForwardUp (Ptr<NetDevice> device, const Packet &packet,
uint16_t protocol, const Address &from)
{
if (m_shutdownRecv)
{
return;
}
Packet p = packet;
PacketSocketAddress address;
address.SetPhysicalAddress (from);
address.SetSingleDevice (device->GetIfIndex ());
address.SetProtocol (protocol);
NS_DEBUG ("PacketSocket::ForwardUp: UID is " << packet.GetUid()
<< " PacketSocket " << this);
if (!m_dummyRxCallback.IsNull ())
{
m_dummyRxCallback (this, p.GetSize (), address);
}
if (!m_rxCallback.IsNull ())
{
m_rxCallback (this, p.PeekData (), p.GetSize (), address);
}
}
}//namespace ns3

133
src/node/packet-socket.h Normal file
View File

@@ -0,0 +1,133 @@
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2007 Emmanuelle Laprise, INRIA
*
* 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
*
* Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>,
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef PACKET_SOCKET_H
#define PACKET_SOCKET_H
#include <stdint.h>
#include "ns3/callback.h"
#include "ns3/ptr.h"
#include "ns3/socket.h"
namespace ns3 {
class Node;
class Packet;
class NetDevice;
class PacketSocketAddress;
/**
* \brief A PacketSocket is a link between an application and a net device.
*
* A PacketSocket can be used to connect an application to a net
* device. The application provides the buffers of data, the socket
* conserts them to a raw packet and the net device then adds the
* protocol specific headers and trailers. This socket type
* is very similar to the linux and BSD "packet" sockets.
*
* Here is a summary of the semantics of this class:
* - Bind: Bind uses only the protocol and device fields of the
* PacketSocketAddress. If none are provided, Bind uses
* zero for both, which means that the socket is bound
* to all protocols on all devices on the node.
*
* - Connect: uses only the protocol, device and "physical address"
* field of the PacketSocketAddress. It is used to set the default
* destination address for outgoing packets.
*
* - Send: send the input packet to the underlying NetDevices
* with the default destination address. The socket must
* be bound and connected.
*
* - SendTo: uses the protocol, device, and "physical address"
* fields of the PacketSocketAddress. The device value is
* used to specialize the packet transmission to a single
* device, the protocol value specifies the protocol of this
* packet only and the "physical address" field is used to override the
* default destination address. The socket must be bound.
*
* - Recv: The address represents the address of the packer originator.
* The fields "physical address", device, and protocol are filled.
*
* - Accept: not allowed
*/
class PacketSocket : public Socket
{
public:
PacketSocket (Ptr<Node> node);
virtual ~PacketSocket ();
virtual enum SocketErrno GetErrno (void) const;
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
virtual int Bind (const Address & address);
virtual int ShutdownSend (void);
virtual int ShutdownRecv (void);
private:
virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
virtual int DoConnect(const Address & address,
Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose);
virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
Callback<void, Ptr<Socket> > closeRequested);
virtual int DoSend (const uint8_t* buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual int DoSendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent);
virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive);
virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
private:
void Init (void);
void ForwardUp (Ptr<NetDevice> device, const Packet &packet,
uint16_t protocol, const Address &from);
int DoBind (const PacketSocketAddress &address);
virtual void DoDispose (void);
enum State {
STATE_OPEN,
STATE_BOUND, // open and bound
STATE_CONNECTED, // open, bound and connected
STATE_CLOSED
};
Ptr<Node> m_node;
Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
Callback<void,Ptr<Socket>,uint8_t const*,uint32_t, const Address &> m_rxCallback;
enum SocketErrno m_errno;
bool m_shutdownSend;
bool m_shutdownRecv;
enum State m_state;
uint16_t m_protocol;
bool m_isSingleDevice;
uint32_t m_device;
Address m_destAddr; /// Default destination address
};
}//namespace ns3
#endif /* PACKET_SOCKET_H */

View File

@@ -5,24 +5,23 @@ namespace ns3 {
Socket::~Socket ()
{}
void
int
Socket::Close(Callback<void, Ptr<Socket> > closeCompleted)
{
DoClose (closeCompleted);
return DoClose (closeCompleted);
}
void
Socket::Connect(const Ipv4Address & address,
uint16_t portNumber,
int
Socket::Connect(const Address & address,
Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose)
{
DoConnect (address, portNumber, connectionSucceeded, connectionFailed, halfClose);
return DoConnect (address, connectionSucceeded, connectionFailed, halfClose);
}
int
Socket::Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
Socket::Accept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
Callback<void, Ptr<Socket> > closeRequested)
{
return DoAccept (connectionRequest, newConnectionCreated, closeRequested);
@@ -35,28 +34,27 @@ Socket::Send (const uint8_t* buffer,
return DoSend (buffer, size, dataSent);
}
int
Socket::SendTo(const Ipv4Address &address,
uint16_t port,
Socket::SendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
return DoSendTo (address, port, buffer, size, dataSent);
return DoSendTo (address, buffer, size, dataSent);
}
void
Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> callback)
Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
{
DoRecv (callback);
}
void
Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> callback)
Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
{
DoRecvDummy (callback);
}
bool
Socket::RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port)
Socket::RefuseAllConnections (Ptr<Socket> socket, const Address& address)
{
return false;
}
@@ -67,14 +65,14 @@ void
Socket::DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t)
{}
void
Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t)
Socket::DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &)
{}
void
Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t,
const Ipv4Address &, uint16_t)
Socket::DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
const Address &)
{}
void
Socket::DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t)
Socket::DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &)
{}

View File

@@ -23,8 +23,8 @@
#include "ns3/callback.h"
#include "ns3/ptr.h"
#include "ipv4-address.h"
#include "ns3/object.h"
#include "address.h"
#include <stdint.h>
namespace ns3 {
@@ -35,8 +35,7 @@ class Node;
* \brief Define a Socket API based on the BSD Socket API.
*
* Contrary to the original BSD socket API, this API is asynchronous:
* it does not contain blocking calls. This API also does not use
* the dreaded BSD sockaddr_t type. Other than that, it tries to stick
* it does not contain blocking calls. Other than that, it tries to stick
* to the BSD API to make it easier those who know the BSD API to use
* this API.
*/
@@ -53,6 +52,9 @@ public:
ERROR_AGAIN,
ERROR_SHUTDOWN,
ERROR_OPNOTSUPP,
ERROR_AFNOSUPPORT,
ERROR_INVAL,
ERROR_BADF,
SOCKET_ERRNO_LAST
};
@@ -69,42 +71,20 @@ public:
virtual Ptr<Node> GetNode (void) const = 0;
/**
* Allocate a free port number and
* bind this socket to this port number on all
* interfaces of this system.
*
* \param address the address to try to allocate
* \returns 0 on success, -1 on failure.
*
* Allocate a local endpoint for this socket.
*/
virtual int Bind (void) = 0;
virtual int Bind (const Address &address) = 0;
/**
* Allocate a free port number and
* bind this socket to this port number on the
* specified interface.
* Allocate a local endpoint for this socket.
*
* \param address address of interface to bind to.
* \returns 0 on success, -1 on failure.
*/
virtual int Bind (Ipv4Address address) = 0;
virtual int Bind () = 0;
/**
* Bind this socket to this port number
* on all interfaces of this system.
*
* \param port port to bind to on all interfaces
* \returns 0 on success, -1 on failure.
*/
virtual int Bind (uint16_t port) = 0;
/**
* Bind this socket to this port number
* on the interface specified by address.
*
* \param address address of interface to bind to.
* \param port port to bind to on specified interface
* \returns 0 on success, -1 on failure.
*/
virtual int Bind (Ipv4Address address, uint16_t port) = 0;
/**
* \brief Close a socket.
@@ -114,7 +94,7 @@ public:
* After the Close call, the socket is no longer valid, and cannot
* safely be used for subsequent operations.
*/
void Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
int Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
/**
* \returns zero on success, -1 on failure.
@@ -134,8 +114,7 @@ public:
/**
* \brief Initiate a connection to a remote host
* \param address IP Address of remote.
* \param portNumber Port number of remote
* \param address Address of remote.
* \param connectionSucceeded this callback is invoked when the connection request
* initiated by the user is successfully completed. The callback is passed
* back a pointer to the same socket object.
@@ -145,11 +124,10 @@ public:
* \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
* other side closes the connection ? Or when I call Close ?
*/
void Connect(const Ipv4Address & address,
uint16_t portNumber,
Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
int Connect(const Address &address,
Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
/**
* \brief Accept connection requests from remote hosts
@@ -170,10 +148,10 @@ public:
* \param closeRequested Callback for connection close request from peer.
* XXX: when is this callback invoked ?
*/
int Accept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest =
int Accept(Callback<bool, Ptr<Socket>, const Address &> connectionRequest =
MakeCallback(&Socket::RefuseAllConnections),
Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated =
MakeCallback (&Socket::DummyCallbackVoidSocketIpv4AddressUi16),
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated =
MakeCallback (&Socket::DummyCallbackVoidSocketAddress),
Callback<void, Ptr<Socket> > closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
/**
@@ -191,15 +169,13 @@ public:
/**
* \brief Send data to a specified peer.
* \param address IP Address of remote host
* \param port port number
* \param buffer Data to send (nil if dummy data).
* \param size Number of bytes to send.
* \param dataSent Data sent callback.
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*/
int SendTo(const Ipv4Address &address,
uint16_t port,
int SendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
@@ -213,8 +189,8 @@ public:
* allocation to hold the dummy memory into a buffer which can be passed
* to the user. Instead, consider using the RecvDummy method.
*/
void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receivedData =
MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16));
void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receivedData =
MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Address));
/**
* \brief Receive data
@@ -223,38 +199,36 @@ public:
* This method is included because it is vastly more efficient than the
* Recv method when you use dummy payload.
*/
void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t> receivedData =
MakeCallback (&Socket::DummyCallbackVoidSocketUi32Ipv4AddressUi16));
void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> receivedData =
MakeCallback (&Socket::DummyCallbackVoidSocketUi32Address));
private:
virtual void DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
virtual void DoConnect(const Ipv4Address & address,
uint16_t portNumber,
Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose) = 0;
virtual int DoAccept(Callback<bool, Ptr<Socket>, const Ipv4Address&, uint16_t> connectionRequest,
Callback<void, Ptr<Socket>, const Ipv4Address&, uint16_t> newConnectionCreated,
virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
virtual int DoConnect(const Address & address,
Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose) = 0;
virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
Callback<void, Ptr<Socket> > closeRequested) = 0;
virtual int DoSend (const uint8_t* buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
virtual int DoSendTo(const Ipv4Address &address,
uint16_t port,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
virtual int DoSendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Ipv4Address&, uint16_t> receive) = 0;
virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Ipv4Address&, uint16_t>) = 0;
virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive) = 0;
virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>) = 0;
static bool RefuseAllConnections (Ptr<Socket> socket, const Ipv4Address& address, uint16_t port);
static bool RefuseAllConnections (Ptr<Socket> socket, const Address& address);
static void DummyCallbackVoidSocket (Ptr<Socket> socket);
static void DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t);
static void DummyCallbackVoidSocketUi32Ipv4AddressUi16 (Ptr<Socket> socket, uint32_t, const Ipv4Address &, uint16_t);
static void DummyCallbackVoidSocketBufferUi32Ipv4AddressUi16 (Ptr<Socket> socket, const uint8_t *, uint32_t,
const Ipv4Address &, uint16_t);
static void DummyCallbackVoidSocketIpv4AddressUi16 (Ptr<Socket> socket, const Ipv4Address &, uint16_t);
static void DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &);
static void DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
const Address &);
static void DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &);
};
} //namespace ns3

View File

@@ -6,11 +6,15 @@ def build(bld):
node.target = node.name
node.uselib_local = ['ns3-core', 'ns3-common', 'ns3-simulator']
node.source = [
'address.cc',
'eui48-address.cc',
'eui64-address.cc',
'inet-socket-address.cc',
'packet-socket-address.cc',
'node.cc',
'ipv4-address.cc',
'net-device.cc',
'mac-address.cc',
'address-utils.cc',
'address-utils.cc',
'llc-snap-header.cc',
'ethernet-header.cc',
'ethernet-trailer.cc',
@@ -21,6 +25,8 @@ def build(bld):
'node-list.cc',
'socket.cc',
'socket-factory.cc',
'packet-socket-factory.cc',
'packet-socket.cc',
'udp.cc',
'ipv4.cc',
'application.cc',
@@ -28,11 +34,15 @@ def build(bld):
headers = bld.create_obj('ns3header')
headers.source = [
'address.h',
'eui48-address.h',
'eui64-address.h',
'inet-socket-address.h',
'packet-socket-address.h',
'node.h',
'ipv4-address.h',
'net-device.h',
'mac-address.h',
'address-utils.h',
'address-utils.h',
'ipv4-route.h',
'queue.h',
'drop-tail-queue.h',
@@ -43,6 +53,7 @@ def build(bld):
'node-list.h',
'socket.h',
'socket-factory.h',
'packet-socket-factory.h',
'udp.h',
'ipv4.h',
'application.h',

View File

@@ -1191,6 +1191,7 @@ GlobalRouteManagerImpl::SPFVertexAddParent (SPFVertex* v)
// ---------------------------------------------------------------------------
#include "ns3/test.h"
#include "ns3/simulator.h"
namespace ns3 {
@@ -1392,6 +1393,9 @@ GlobalRouteManagerImplTest::RunTests (void)
// because the NodeList is empty
srm->DebugSPFCalculate (lsa0->GetLinkStateId ()); // node n0
Simulator::Run ();
Simulator::Destroy ();
// This delete clears the srm, which deletes the LSDB, which clears
// all of the LSAs, which each destroys the attached LinkRecords.
delete srm;

View File

@@ -332,6 +332,13 @@ GlobalRouter::~GlobalRouter ()
ClearLSAs();
}
void
GlobalRouter::DoDispose ()
{
m_node = 0;
Object::DoDispose ();
}
void
GlobalRouter::ClearLSAs ()
{
@@ -535,8 +542,7 @@ GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const
GlobalRouter::GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const
{
uint32_t nDevices = ch->GetNDevices();
NS_ASSERT_MSG(nDevices == 2,
NS_ASSERT_MSG(ch->GetNDevices() == 2,
"GlobalRouter::GetAdjacent (): Channel with other than two devices");
//
// This is a point to point channel with two endpoints. Get both of them.

View File

@@ -565,6 +565,8 @@ protected:
Ipv4Address m_routerId;
private:
// inherited from Object
virtual void DoDispose (void);
/**
* @brief Global Router copy construction is disallowed.
*/