merge with ns-3-dev
This commit is contained in:
1
.hgtags
1
.hgtags
@@ -4,3 +4,4 @@
|
||||
38099dd26e9467b8f49f8632f22789858149a6e7 release ns-3.0.3
|
||||
5701e60bf01a8ac1308945e69001e0cc07948faf release ns-3.0.4
|
||||
08046b6aef37932507696a2f2f427b42d693781e release ns-3.0.5
|
||||
267e2ebc28e4e4ae2f579e1cfc29902acade0c34 buffer-working-before-breaking
|
||||
|
||||
235
README.multicast-routing
Normal file
235
README.multicast-routing
Normal file
@@ -0,0 +1,235 @@
|
||||
Static multicast routing overview
|
||||
--------------------------------
|
||||
|
||||
This is brief documentation of a proposal to add static multicast
|
||||
routing to ns-3.
|
||||
|
||||
This extension allows the simulation user to:
|
||||
|
||||
- manually add Ipv4 multicast routes to a router
|
||||
- specify a default outgoing interface for multicast sources (hosts) in
|
||||
various ways
|
||||
- allow a multicast receiver (hosts) to join a multicast group, to enable
|
||||
reception of that group's datagrams
|
||||
|
||||
1. Code location:
|
||||
|
||||
- http://code.nsnam.org/craigdo/ns-3-mc
|
||||
|
||||
- the main source code is found in src/internet-node/ipv4-static-routing.{cc,h}
|
||||
|
||||
also touched are:
|
||||
- src/internet-node/ipv4-l3-protocol.cc (forwarding methods for the
|
||||
static routing API)
|
||||
- src/node/net-device.cc (provides virtual NetDevice::MakeMulticastAddress)
|
||||
- src/arp-ipv4-interface.cc (calls NetDevice::MakeMulticastAddress)
|
||||
- src/devices/csma/csma-net-device.cc (handles multicast addressing and
|
||||
reception).
|
||||
- src/devices/point-to-point/point-to-point-net-device.cc (implements required
|
||||
virtual methods.
|
||||
- src/internet-node/ (several files have added tracing)
|
||||
|
||||
- a heavily commented example script is in examples/csma-multicast.cc
|
||||
|
||||
2. API:
|
||||
|
||||
The API for adding a multicast route is:
|
||||
|
||||
/**
|
||||
* @brief Add a multicast route to the static routing table.
|
||||
*
|
||||
* A multicast route must specify an origin IP address, a multicast group and
|
||||
* an input network interface index as conditions and provide a vector of
|
||||
* output network interface indices over which packets matching the conditions
|
||||
* are sent.
|
||||
*
|
||||
* Typically there are two main types of multicast routes: routes of the
|
||||
* first kind are used during forwarding. All of the conditions must be
|
||||
* exlicitly provided. The second kind of routes are used to get packets off
|
||||
* of a local node. The difference is in the input interface. Routes for
|
||||
* forwarding will always have an explicit input interface specified. Routes
|
||||
* off of a node will always set the input interface to a wildcard specified
|
||||
* by the index Ipv4RoutingProtocol::IF_INDEX_ANY.
|
||||
*
|
||||
* For routes off of a local node wildcards may be used in the origin and
|
||||
* multicast group addresses. The wildcard used for Ipv4Adresses is that
|
||||
* address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage
|
||||
* of a wildcard allows one to specify default behavior to varying degrees.
|
||||
*
|
||||
* For example, making the origin address a wildcard, but leaving the
|
||||
* multicast group specific allows one (in the case of a node with multiple
|
||||
* interfaces) to create different routes using different output interfaces
|
||||
* for each multicast group.
|
||||
*
|
||||
* If the origin and multicast addresses are made wildcards, you have created
|
||||
* essentially a default multicast address that can forward to multiple
|
||||
* interfaces. Compare this to the actual default multicast address that is
|
||||
* limited to specifying a single output interface for compatibility with
|
||||
* existing functionality in other systems.
|
||||
*
|
||||
* @param origin The Ipv4Address of the origin of packets for this route. May
|
||||
* be Ipv4Address:GetAny for open groups.
|
||||
* @param group The Ipv4Address of the multicast group or this route.
|
||||
* @param inputInterface The input network interface index over which to
|
||||
* expect packets destined for this route. May be
|
||||
* Ipv4RoutingProtocol::IF_INDEX_ANY for packets of local origin.
|
||||
* @param outputInterface A vector of network interface indices used to specify
|
||||
* how to send packets to the destination(s).
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
Ipv4::AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces)
|
||||
|
||||
To remove a route, one uses:
|
||||
|
||||
/**
|
||||
* @brief Remove a route from the static multicast routing table.
|
||||
*
|
||||
* Externally, the multicast static routing table appears simply as a table
|
||||
* with n entries. The one sublety of note is that if a default multicast
|
||||
* route has been set it will appear as the zeroth entry in the table. This
|
||||
* means that the default route may be removed by calling this method with
|
||||
* appropriate wildcard parameters.
|
||||
*
|
||||
* This method causes the multicast routing table to be searched for the first
|
||||
* route that matches the parameters and removes it.
|
||||
*
|
||||
* Wildcards may be provided to this function, but the wildcards are used to
|
||||
* exacly match wildcards in the routes (see AddMulticastRoute). That is,
|
||||
* calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
|
||||
* remove routes with any address in the origin, but will only remove routes
|
||||
* with "0.0.0.0" set as the the origin.
|
||||
*
|
||||
* @param origin The IP address specified as the origin of packets for the
|
||||
* route.
|
||||
* @param origin The IP address specified as the multicast group addres of
|
||||
* the route.
|
||||
* @param inputInterfade The network interface index specified as the expected
|
||||
* input interface for the route.
|
||||
* @returns True if a route was found and removed, false otherwise.
|
||||
*
|
||||
* @see Ipv4MulticastRoute
|
||||
* @see Ipv4StaticRouting::AddMulticastRoute
|
||||
*/
|
||||
Ipv4::RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface)
|
||||
|
||||
For symmetry with the unicast routing interface, a method is provided to
|
||||
remove routes by index:
|
||||
|
||||
/**
|
||||
* @brief Remove a route from the static multicast routing table.
|
||||
*
|
||||
* Externally, the multicast static routing table appears simply as a table
|
||||
* with n entries. The one sublety of note is that if a default multicast
|
||||
* route has been set it will appear as the zeroth entry in the table. This
|
||||
* means that if the default route has been set, calling
|
||||
* RemoveMulticastRoute (0) will remove the default route.
|
||||
*
|
||||
* @param index The index (into the multicast routing table) of the route to
|
||||
* remove. If the default route has been set, it will occupy index zero.
|
||||
*
|
||||
* @see Ipv4Route
|
||||
* @see Ipv4StaticRouting::GetRoute
|
||||
* @see Ipv4StaticRouting::AddRoute
|
||||
*/
|
||||
void RemoveMulticastRoute (uint32_t index);
|
||||
|
||||
For compatibility, and to provide simplicity, one can set a default multicast
|
||||
route for a host originating data:
|
||||
|
||||
/**
|
||||
* @brief Add a default multicast route to the static routing table.
|
||||
*
|
||||
* This is the multicast equivalent of the unicast version SetDefaultRoute.
|
||||
* We tell the routing system what to do in the case where a specific route
|
||||
* to a destination multicast group is not found. The system forwards
|
||||
* packets out the specified interface in the hope that "something out there"
|
||||
* knows better how to route the packet. This method is only used in
|
||||
* initially sending packets off of a host. The default multicast route is
|
||||
* not consulted during forwarding -- exact routes must be specified using
|
||||
* AddMulticastRoute for that case.
|
||||
*
|
||||
* Since we're basically sending packets to some entity we think may know
|
||||
* better what to do, we don't pay attention to "subtleties" like origin
|
||||
* address, nor do we worry about forwarding out multiple interfaces. If the
|
||||
* default multicast route is set, it is returned as the selected route from
|
||||
* LookupStatic irrespective of origin or multicast group if another specific
|
||||
* route is not found.
|
||||
*
|
||||
* @param outputInterface The network interface index used to specify where
|
||||
* to send packets in the case of unknown routes.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
Ipv4::SetDefaultMulticastRoute (uint32_t outputInterface)
|
||||
|
||||
For a host wanting to receive multicast data, the following function is used
|
||||
to join each multicast group.
|
||||
|
||||
/**
|
||||
* \brief Join a multicast group for a given multicast source and
|
||||
* group.
|
||||
*
|
||||
* \param origin The Ipv4 address of the multicast source.
|
||||
* \param group The multicast group address.
|
||||
*/
|
||||
Ipv4::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
|
||||
|
||||
To stop receiving multicast data, the following function is used:
|
||||
|
||||
/**
|
||||
* \brief Leave a multicast group for a given multicast source and
|
||||
* group.
|
||||
*
|
||||
* \param origin The Ipv4 address of the multicast source.
|
||||
* \param group The multicast group address.
|
||||
*/
|
||||
LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
|
||||
|
||||
There are new lookup functions implemented in Ipv4:
|
||||
|
||||
/**
|
||||
* \brief Find and return the interface ID of the interface that has been
|
||||
* assigned the specified IP address.
|
||||
* \param addr The IP address assigned to the interface of interest.
|
||||
* \returns The index of the ipv4 interface with the given address.
|
||||
*
|
||||
* Each IP interface has an IP address associated with it. It is often
|
||||
* useful to search the list of interfaces for one that corresponds to
|
||||
* a known IP Address. This call takes an IP address as a parameter and
|
||||
* returns the interface index of the first interface that has been assigned
|
||||
* that address. If the address is not found, this function asserts.
|
||||
*/
|
||||
Ipv4::FindInterfaceForAddr (Ipv4Address addr) const;
|
||||
|
||||
/**
|
||||
* \brief Find and return the interface ID of the interface that has been
|
||||
* assigned the specified (masked) IP address.
|
||||
* \param addr The IP address assigned to the interface of interest.
|
||||
* \param mask The address mask to be used in address matching.
|
||||
* \returns The index of the ipv4 interface with the given address.
|
||||
*
|
||||
* Each IP interface has an IP address associated with it. It is often
|
||||
* useful to search the list of interfaces for one that corresponds to
|
||||
* a known IP Address. This call takes an IP address and an IP address
|
||||
* mask as parameters and returns the interface index of the first interface
|
||||
* that matches the masked IP address.
|
||||
*/
|
||||
Ipv4::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const;
|
||||
|
||||
Also, there are various methods to lookup and iterate the static multicast
|
||||
routes of a node, in the Ipv4StaticRouting class.
|
||||
|
||||
3. Dependencies:
|
||||
|
||||
- fix for bug 69 (source Ipv4 address is set correctly for UDP)
|
||||
- fix for OnOffApplication that receives data
|
||||
|
||||
4. Open issues or features not included
|
||||
|
||||
- choose source interface on a per-group basis when a host is multihomed
|
||||
@@ -66,13 +66,24 @@ int main (int argc, char *argv[])
|
||||
|
||||
// Users may find it convenient to turn on explicit debugging
|
||||
// for selected modules; the below lines suggest how to do this
|
||||
#if 0
|
||||
DebugComponentEnable("CsmaNetDevice");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("NetDevice");
|
||||
#if 0
|
||||
DebugComponentEnable("Object");
|
||||
DebugComponentEnable("Queue");
|
||||
DebugComponentEnable("DropTailQueue");
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("CsmaChannel");
|
||||
DebugComponentEnable("NetDevice");
|
||||
DebugComponentEnable("CsmaNetDevice");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("OnOffApplication");
|
||||
DebugComponentEnable("PacketSocket");
|
||||
DebugComponentEnable("UdpSocket");
|
||||
DebugComponentEnable("UdpL4Protocol");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("Ipv4StaticRouting");
|
||||
DebugComponentEnable("Ipv4Interface");
|
||||
DebugComponentEnable("ArpIpv4Interface");
|
||||
DebugComponentEnable("Ipv4LoopbackInterface");
|
||||
#endif
|
||||
|
||||
// Set up some default values for the simulation. Use the Bind()
|
||||
@@ -103,13 +114,13 @@ int main (int argc, char *argv[])
|
||||
CsmaTopology::CreateCsmaChannel(
|
||||
DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
uint32_t n0ifIndex0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0,
|
||||
uint32_t n0ifIndex0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, channel0,
|
||||
Eui48Address("10:54:23:54:0:50"));
|
||||
uint32_t n0ifIndex1 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel1,
|
||||
uint32_t n0ifIndex1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, channel1,
|
||||
Eui48Address("10:54:23:54:0:51"));
|
||||
uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
|
||||
uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, channel0,
|
||||
Eui48Address("10:54:23:54:23:51"));
|
||||
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel1,
|
||||
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, channel1,
|
||||
Eui48Address("10:54:23:54:23:52"));
|
||||
|
||||
// Later, we add IP addresses.
|
||||
@@ -125,6 +136,18 @@ int main (int argc, char *argv[])
|
||||
CsmaIpv4Topology::AddIpv4Address (
|
||||
n2, n2ifIndex, Ipv4Address("192.168.1.2"), Ipv4Mask("255.255.255.0"));
|
||||
|
||||
// XXX Is this the right thing to do?
|
||||
//
|
||||
// The OnOff application uses a connected socket. This socket needs to be
|
||||
// able to figure out which interface to use as the source address for
|
||||
// packets. When there's one interface, this isn't too hard, but node zero
|
||||
// has two interfaces, and limited broadcasts will be sent out both of those
|
||||
// interfaces. We need to provide some way to disambiguate the choice.
|
||||
// If we supply a default route, the specified interface will be chosen.
|
||||
|
||||
Ptr<Ipv4> ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
ipv4->SetDefaultRoute ("192.168.1.3", n0ifIndex0);
|
||||
|
||||
// Create the OnOff application to send UDP datagrams of size
|
||||
// 210 bytes at a rate of 448 Kb/s
|
||||
// from n0 to n1
|
||||
|
||||
312
examples/csma-multicast.cc
Normal file
312
examples/csma-multicast.cc
Normal file
@@ -0,0 +1,312 @@
|
||||
/* -*- 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
|
||||
*/
|
||||
|
||||
// Network topology
|
||||
//
|
||||
// Lan1
|
||||
// ===========
|
||||
// | | |
|
||||
// n0 n1 n2 n3 n4
|
||||
// | | |
|
||||
// ===========
|
||||
// Lan0
|
||||
//
|
||||
// - Multicast source is at node n0;
|
||||
// - Multicast forwarded by node n2 onto LAN1;
|
||||
// - Nodes n0, n1, n2, n3, and n4 receive the multicast frame.
|
||||
// - Node n4 listens for the data (actual listener not yet implementted)
|
||||
|
||||
#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-channel.h"
|
||||
#include "ns3/csma-net-device.h"
|
||||
#include "ns3/csma-topology.h"
|
||||
#include "ns3/csma-ipv4-topology.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"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("CsmaMulticast");
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
//
|
||||
// Users may find it convenient to turn on explicit debugging
|
||||
// for selected modules; the below lines suggest how to do this
|
||||
//
|
||||
#if 0
|
||||
DebugComponentEnable("CsmaMulticast");
|
||||
|
||||
DebugComponentEnable("Object");
|
||||
DebugComponentEnable("Queue");
|
||||
DebugComponentEnable("DropTailQueue");
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("CsmaChannel");
|
||||
DebugComponentEnable("NetDevice");
|
||||
DebugComponentEnable("CsmaNetDevice");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("OnOffApplication");
|
||||
DebugComponentEnable("PacketSocket");
|
||||
DebugComponentEnable("UdpSocket");
|
||||
DebugComponentEnable("UdpL4Protocol");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("Ipv4StaticRouting");
|
||||
DebugComponentEnable("Ipv4Interface");
|
||||
DebugComponentEnable("ArpIpv4Interface");
|
||||
DebugComponentEnable("Ipv4LoopbackInterface");
|
||||
#endif
|
||||
|
||||
//
|
||||
// Set up default values for the simulation. Use the DefaultValue::Bind()
|
||||
// technique to tell the system what subclass of Queue to use. The Bind
|
||||
// command command tells the queue factory which class to instantiate when the
|
||||
// queue factory is invoked in the topology code
|
||||
//
|
||||
DefaultValue::Bind ("Queue", "DropTailQueue");
|
||||
//
|
||||
// Allow the user to override any of the defaults and the above Bind() at
|
||||
// run-time, via command-line arguments
|
||||
//
|
||||
CommandLine::Parse (argc, argv);
|
||||
//
|
||||
// Explicitly create the nodes required by the topology (shown above).
|
||||
//
|
||||
NS_DEBUG("Create nodes.");
|
||||
Ptr<Node> n0 = Create<InternetNode> ();
|
||||
Ptr<Node> n1 = Create<InternetNode> ();
|
||||
Ptr<Node> n2 = Create<InternetNode> ();
|
||||
Ptr<Node> n3 = Create<InternetNode> ();
|
||||
Ptr<Node> n4 = Create<InternetNode> ();
|
||||
|
||||
NS_DEBUG("Create channels.");
|
||||
//
|
||||
// Explicitly create the channels required by the topology (shown above).
|
||||
//
|
||||
Ptr<CsmaChannel> lan0 =
|
||||
CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
Ptr<CsmaChannel> lan1 =
|
||||
CsmaTopology::CreateCsmaChannel(DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
NS_DEBUG("Build Topology.");
|
||||
//
|
||||
// Now fill out the topology by creating the net devices required to connect
|
||||
// the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will
|
||||
// create a net device, add a MAC address (in memory of the pink flamingo) and
|
||||
// connect the net device to a nodes and also to a channel. the
|
||||
// AddIpv4CsmaNetDevice method returns a net device index for the net device
|
||||
// created on the node. Interpret nd0 as the net device we created for node
|
||||
// zero. Interpret nd2Lan0 as the net device we created for node two to
|
||||
// connect to Lan0.
|
||||
//
|
||||
uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan0,
|
||||
Eui48Address("08:00:2e:00:00:00"));
|
||||
uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan0,
|
||||
Eui48Address("08:00:2e:00:00:01"));
|
||||
uint32_t nd2Lan0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan0,
|
||||
Eui48Address("08:00:2e:00:00:02"));
|
||||
|
||||
uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1,
|
||||
Eui48Address("08:00:2e:00:00:03"));
|
||||
uint32_t nd3 __attribute__ ((unused)) =
|
||||
CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1,
|
||||
Eui48Address("08:00:2e:00:00:04"));
|
||||
uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1,
|
||||
Eui48Address("08:00:2e:00:00:05"));
|
||||
|
||||
NS_DEBUG ("nd0 = " << nd0);
|
||||
NS_DEBUG ("nd1 = " << nd1);
|
||||
NS_DEBUG ("nd2Lan0 = " << nd2Lan0);
|
||||
NS_DEBUG ("nd2Lan1 = " << nd2Lan1);
|
||||
NS_DEBUG ("nd3 = " << nd3);
|
||||
NS_DEBUG ("nd4 = " << nd3);
|
||||
//
|
||||
// We've got the "hardware" in place. Now we need to add IP addresses.
|
||||
//
|
||||
NS_DEBUG("Assign IP Addresses.");
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address ("10.1.1.1"),
|
||||
Ipv4Mask ("255.255.255.0"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address ("10.1.1.2"),
|
||||
Ipv4Mask ("255.255.255.0"));
|
||||
|
||||
//
|
||||
// We'll need these addresses later
|
||||
//
|
||||
Ipv4Address n2Lan0Addr ("10.1.1.3");
|
||||
Ipv4Address n2Lan1Addr ("10.1.2.1");
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, n2Lan0Addr,
|
||||
Ipv4Mask ("255.255.255.0"));
|
||||
//
|
||||
// Assign IP addresses to the net devices and associated interfaces on Lan1
|
||||
//
|
||||
CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, n2Lan1Addr,
|
||||
Ipv4Mask ("255.255.255.0"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (n3, nd1, Ipv4Address ("10.1.2.2"),
|
||||
Ipv4Mask ("255.255.255.0"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (n4, nd4, Ipv4Address ("10.1.2.3"),
|
||||
Ipv4Mask ("255.255.255.0"));
|
||||
|
||||
NS_DEBUG("Configure multicasting.");
|
||||
//
|
||||
// Now we can configure multicasting. As described above, the multicast
|
||||
// source is at node zero, which we assigned the IP address of 10.1.1.1
|
||||
// earlier. We need to define a multicast group to send packets to. This
|
||||
// can be any multicast address from 224.0.0.0 through 239.255.255.255
|
||||
// (avoiding the reserved routing protocol addresses). We just pick a
|
||||
// convenient number (225.0.0.0) and or in some bits to let us verify that
|
||||
// correct Ethernet multicast addresses are constructed down in the system.
|
||||
//
|
||||
Ipv4Address multicastSource ("10.1.1.1");
|
||||
Ipv4Address multicastGroup ("225.1.2.4");
|
||||
//
|
||||
// We are going to manually configure multicast routing. This means telling
|
||||
// node two that it should expect multicast data coming from IP address
|
||||
// 10.1.1.1 originally. It should expect these data coming in over its IP
|
||||
// interface connected to Lan0. When node two receives these packets, they
|
||||
// should be forwarded out the interface that connects it to Lan1.
|
||||
//
|
||||
// We're going to need the interface indices on node two corresponding to
|
||||
// these interfaces, which we call ifIndexLan0 and ifIndexLan1. The most
|
||||
// general way to get these interfaces is to look them up by IP address.
|
||||
// Looking back to the topology creation calls above, we saved the addresses
|
||||
// assigned to the interface connecting node two to Lan0 and Lan1. Now is
|
||||
// a fine time to find the interface indices on node two.
|
||||
//
|
||||
Ptr<Ipv4> ipv4;
|
||||
ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
|
||||
uint32_t ifIndexLan0 = ipv4->FindInterfaceForAddr (n2Lan0Addr);
|
||||
uint32_t ifIndexLan1 = ipv4->FindInterfaceForAddr (n2Lan1Addr);
|
||||
//
|
||||
// Now, we need to do is to call the AddMulticastRoute () method on node
|
||||
// two's Ipv4 interface and tell it that whenever it receives a packet on
|
||||
// the interface from Lan0, with the packet from the multicast source,
|
||||
// destined for the multicast group, it should forward these packets down
|
||||
// the interface connecting it to Lan1. (Note: the vector of output
|
||||
// interfaces is in case there are multiple net devices on a node -- not
|
||||
// true in this case).
|
||||
//
|
||||
std::vector<uint32_t> outputInterfaces (1);
|
||||
outputInterfaces[0] = ifIndexLan1;
|
||||
|
||||
ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexLan0,
|
||||
outputInterfaces);
|
||||
//
|
||||
// We need to specify how the source node handles multicasting. There are a
|
||||
// number of ways we can deal with this, we just need to pick one. The first
|
||||
// method is to add an explicit route out of the source node, just as we did
|
||||
// for the forwarding node. Use this method when you want to send packets out
|
||||
// multiple interfaces or send packets out different interfaces based on the
|
||||
// differing multicast groups. Since the source is local, there will be no
|
||||
// input interface over which packets are received, so use
|
||||
// Ipv4RoutingProtocol::IF_INDEX_ANY as a wildcard.
|
||||
//
|
||||
// A second way is to specify a multicast route using wildcards. If you
|
||||
// want to send multicasts out differing sets of interfaces based on the
|
||||
// multicast group, you can use AddMulticastRoute () but specify the origin
|
||||
// as a wildcard. If you want all multicasts to go out a single set of
|
||||
// interfaces, you can make both the origin and group a wildcard.
|
||||
//
|
||||
// If you have a simple system, where the source has a single interface, this
|
||||
// can be done via the SetDefaultMulticastRoute () method on the Ipv4
|
||||
// interface. This tells the system to send all multicasts out a single
|
||||
// specified network interface index.
|
||||
//
|
||||
// A last way is to specify a (or use an existing) default unicast route. The
|
||||
// multicast routing code uses the unicast default route as a multicast "route
|
||||
// of last resort." this method for is also on Ipv4 and is called
|
||||
// SetDefaultRoute ().
|
||||
//
|
||||
// Since this is a simple multicast example, we use the
|
||||
// SetDefaultMulticastRoute () approach. We are going to first need the
|
||||
// Ipv4 interface for node 0 which is the multicast source. We use this
|
||||
// interface to find the output interface index, and tell node zero to send
|
||||
// its multicast traffic out that interface.
|
||||
//
|
||||
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
uint32_t ifIndexSrc = ipv4->FindInterfaceForAddr (multicastSource);
|
||||
ipv4->SetDefaultMulticastRoute (ifIndexSrc);
|
||||
//
|
||||
// As described above, node four will be the only node listening for the
|
||||
// multicast data. To enable forwarding bits up the protocol stack, we need
|
||||
// to tell the stack to join the multicast group.
|
||||
//
|
||||
ipv4 = n4->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
|
||||
//
|
||||
// Create an OnOff application to send UDP datagrams from node zero to the
|
||||
// multicast group (node four will be listening).
|
||||
//
|
||||
NS_DEBUG("Create Applications.");
|
||||
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
|
||||
n0,
|
||||
InetSocketAddress (multicastGroup, 80),
|
||||
"Udp",
|
||||
ConstantVariable(1),
|
||||
ConstantVariable(0),
|
||||
DataRate ("255b/s"),
|
||||
128);
|
||||
//
|
||||
// Tell the application when to start and stop.
|
||||
//
|
||||
ooff->Start(Seconds(1.));
|
||||
ooff->Stop (Seconds(10.));
|
||||
//
|
||||
// Configure tracing of all enqueue, dequeue, and NetDevice receive events.
|
||||
// Trace output will be sent to the file "csma-multicast.tr"
|
||||
//
|
||||
NS_DEBUG("Configure Tracing.");
|
||||
AsciiTrace asciitrace ("csma-multicast.tr");
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
asciitrace.TraceAllQueues ();
|
||||
//
|
||||
// Also configure some tcpdump traces; each interface will be traced.
|
||||
// The output files will be named:
|
||||
// csma-multicast.pcap-<nodeId>-<interfaceId>
|
||||
// and can be read by the "tcpdump -r" command (use "-tt" option to
|
||||
// display timestamps correctly)
|
||||
//
|
||||
PcapTrace pcaptrace ("csma-multicast.pcap");
|
||||
pcaptrace.TraceAllIp ();
|
||||
//
|
||||
// Now, do the actual simulation.
|
||||
//
|
||||
NS_DEBUG("Run Simulation.");
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
NS_DEBUG("Done.");
|
||||
}
|
||||
@@ -14,35 +14,25 @@
|
||||
* 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
|
||||
// | | | |
|
||||
// =====================
|
||||
// =================
|
||||
// LAN
|
||||
//
|
||||
// - 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)
|
||||
// - CBR/UDP flows from n0 to n1 and from n3 to n0
|
||||
// - DropTail queues
|
||||
// - Tracing of queues and packet receptions to file "csma-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"
|
||||
@@ -58,109 +48,168 @@
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/onoff-application.h"
|
||||
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("CsmaOneSubnet");
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
// Users may find it convenient to turn on explicit debugging
|
||||
// for selected modules; the below lines suggest how to do this
|
||||
//
|
||||
// Users may find it convenient to turn on explicit debugging
|
||||
// for selected modules; the below lines suggest how to do this
|
||||
//
|
||||
#if 0
|
||||
DebugComponentEnable("CsmaOneSubnet");
|
||||
|
||||
DebugComponentEnable("Object");
|
||||
DebugComponentEnable("Queue");
|
||||
DebugComponentEnable("DropTailQueue");
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("CsmaChannel");
|
||||
DebugComponentEnable("CsmaNetDevice");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("NetDevice");
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("CsmaChannel");
|
||||
DebugComponentEnable("PacketSocket");
|
||||
DebugComponentEnable("OnOffApplication");
|
||||
DebugComponentEnable("UdpSocket");
|
||||
DebugComponentEnable("UdpL4Protocol");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("Ipv4StaticRouting");
|
||||
DebugComponentEnable("Ipv4Interface");
|
||||
DebugComponentEnable("ArpIpv4Interface");
|
||||
DebugComponentEnable("Ipv4LoopbackInterface");
|
||||
#endif
|
||||
|
||||
// Set up some default values for the simulation. Use the Bind()
|
||||
// technique to tell the system what subclass of Queue to use,
|
||||
// and what the queue limit is
|
||||
|
||||
// The below Bind command tells the queue factory which class to
|
||||
// instantiate, when the queue factory is invoked in the topology code
|
||||
//
|
||||
// Set up default values for the simulation. Use the DefaultValue::Bind()
|
||||
// technique to tell the system what subclass of Queue to use. The Bind
|
||||
// command command tells the queue factory which class to instantiate when the
|
||||
// queue factory is invoked in the topology code
|
||||
//
|
||||
DefaultValue::Bind ("Queue", "DropTailQueue");
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// Bind()s at run-time, via command-line arguments
|
||||
//
|
||||
// Allow the user to override any of the defaults and the above Bind() at
|
||||
// run-time, via command-line arguments
|
||||
//
|
||||
CommandLine::Parse (argc, argv);
|
||||
|
||||
// Here, we will explicitly create four nodes. In more sophisticated
|
||||
// topologies, we could configure a node factory.
|
||||
//
|
||||
// Explicitly create the nodes required by the topology (shown above).
|
||||
//
|
||||
NS_DEBUG("Create nodes.");
|
||||
Ptr<Node> n0 = Create<InternetNode> ();
|
||||
Ptr<Node> n1 = Create<InternetNode> ();
|
||||
Ptr<Node> n2 = Create<InternetNode> ();
|
||||
Ptr<Node> n3 = Create<InternetNode> ();
|
||||
|
||||
// We create the channels first without any IP addressing information
|
||||
Ptr<CsmaChannel> channel0 =
|
||||
CsmaTopology::CreateCsmaChannel(
|
||||
DataRate(5000000), MilliSeconds(2));
|
||||
NS_DEBUG("Create channels.");
|
||||
//
|
||||
// Explicitly create the channels required by the topology (shown above).
|
||||
//
|
||||
Ptr<CsmaChannel> lan = CsmaTopology::CreateCsmaChannel(
|
||||
DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0,
|
||||
Eui48Address("10:54:23:54:23:50"));
|
||||
uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
|
||||
Eui48Address("10:54:23:54:23:51"));
|
||||
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0,
|
||||
Eui48Address("10:54:23:54:23:52"));
|
||||
uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0,
|
||||
Eui48Address("10:54:23:54:23:53"));
|
||||
NS_DEBUG("Build Topology.");
|
||||
//
|
||||
// Now fill out the topology by creating the net devices required to connect
|
||||
// the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will
|
||||
// create a net device, add a MAC address (in memory of the pink flamingo) and
|
||||
// connect the net device to a nodes and also to a channel. the
|
||||
// AddIpv4CsmaNetDevice method returns a net device index for the net device
|
||||
// created on the node. Interpret nd0 as the net device we created for node
|
||||
// zero.
|
||||
//
|
||||
uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan,
|
||||
Eui48Address("08:00:2e:00:00:00"));
|
||||
|
||||
// Later, we add IP addresses.
|
||||
CsmaIpv4Topology::AddIpv4Address (
|
||||
n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
|
||||
uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan,
|
||||
Eui48Address("08:00:2e:00:00:01"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (
|
||||
n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
|
||||
uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan,
|
||||
Eui48Address("08:00:2e:00:00:02"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (
|
||||
n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
|
||||
uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan,
|
||||
Eui48Address("08:00:2e:00:00:03"));
|
||||
|
||||
NS_DEBUG ("nd0 = " << nd0);
|
||||
NS_DEBUG ("nd1 = " << nd1);
|
||||
NS_DEBUG ("nd2 = " << nd2);
|
||||
NS_DEBUG ("nd3 = " << nd3);
|
||||
//
|
||||
// We've got the "hardware" in place. Now we need to add IP addresses.
|
||||
//
|
||||
NS_DEBUG("Assign IP Addresses.");
|
||||
//
|
||||
// XXX BUGBUG
|
||||
// Need a better way to get the interface index. The point-to-point topology
|
||||
// as implemented can't return the index since it creates interfaces on both
|
||||
// sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a
|
||||
// method on Ipv4 to find the interface index corresponding to a given ipv4
|
||||
// address.
|
||||
//
|
||||
// Assign IP addresses to the net devices and associated interfaces
|
||||
// on the lan. The AddIpv4Address method returns an Ipv4 interface index
|
||||
// which we do not need here.
|
||||
//
|
||||
CsmaIpv4Topology::AddIpv4Address (n0, nd0, Ipv4Address("10.1.1.1"),
|
||||
Ipv4Mask("255.255.255.0"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (n1, nd1, Ipv4Address("10.1.1.2"),
|
||||
Ipv4Mask("255.255.255.0"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (n2, nd2, Ipv4Address("10.1.1.3"),
|
||||
Ipv4Mask("255.255.255.0"));
|
||||
|
||||
CsmaIpv4Topology::AddIpv4Address (
|
||||
n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
|
||||
|
||||
// Create the OnOff application to send UDP datagrams of size
|
||||
// 210 bytes at a rate of 448 Kb/s
|
||||
// from n0 to n1
|
||||
CsmaIpv4Topology::AddIpv4Address (n3, nd3, Ipv4Address("10.1.1.4"),
|
||||
Ipv4Mask("255.255.255.0"));
|
||||
//
|
||||
// Create an OnOff application to send UDP datagrams from node zero to node 1.
|
||||
//
|
||||
NS_DEBUG("Create Applications.");
|
||||
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
|
||||
n0,
|
||||
InetSocketAddress ("10.1.1.2", 80),
|
||||
"Udp",
|
||||
ConstantVariable(1),
|
||||
ConstantVariable(0));
|
||||
// Start the application
|
||||
//
|
||||
// Tell the application when to start and stop.
|
||||
//
|
||||
ooff->Start(Seconds(1.0));
|
||||
ooff->Stop (Seconds(10.0));
|
||||
|
||||
// Create a similar flow from n3 to n0, starting at time 1.1 seconds
|
||||
//
|
||||
// Create a similar flow from n3 to n0, starting at time 1.1 seconds
|
||||
//
|
||||
ooff = Create<OnOffApplication> (
|
||||
n3,
|
||||
InetSocketAddress ("10.1.1.1", 80),
|
||||
"Udp",
|
||||
ConstantVariable(1),
|
||||
ConstantVariable(0));
|
||||
// Start the application
|
||||
|
||||
ooff->Start(Seconds(1.1));
|
||||
ooff->Stop (Seconds(10.0));
|
||||
|
||||
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
|
||||
// Trace output will be sent to the csma-one-subnet.tr file
|
||||
//
|
||||
// Configure tracing of all enqueue, dequeue, and NetDevice receive events.
|
||||
// Trace output will be sent to the file "csma-one-subnet.tr"
|
||||
//
|
||||
NS_DEBUG("Configure Tracing.");
|
||||
AsciiTrace asciitrace ("csma-one-subnet.tr");
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
asciitrace.TraceAllQueues ();
|
||||
|
||||
// Also configure some tcpdump traces; each interface will be traced
|
||||
// The output files will be named
|
||||
// simple-point-to-point.pcap-<nodeId>-<interfaceId>
|
||||
// and can be read by the "tcpdump -r" command (use "-tt" option to
|
||||
// display timestamps correctly)
|
||||
//
|
||||
// Also configure some tcpdump traces; each interface will be traced.
|
||||
// The output files will be named:
|
||||
// csma-one-subnet.pcap-<nodeId>-<interfaceId>
|
||||
// and can be read by the "tcpdump -r" command (use "-tt" option to
|
||||
// display timestamps correctly)
|
||||
//
|
||||
PcapTrace pcaptrace ("csma-one-subnet.pcap");
|
||||
pcaptrace.TraceAllIp ();
|
||||
|
||||
//
|
||||
// Now, do the actual simulation.
|
||||
//
|
||||
NS_DEBUG("Run Simulation.");
|
||||
Simulator::Run ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
NS_DEBUG("Done.");
|
||||
}
|
||||
|
||||
@@ -128,13 +128,13 @@ int main (int argc, char *argv[])
|
||||
CsmaTopology::CreateCsmaChannel(
|
||||
DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channelc0,
|
||||
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, channelc0,
|
||||
Eui48Address("10:54:23:54:23:50"));
|
||||
uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channelc0,
|
||||
uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, channelc0,
|
||||
Eui48Address("10:54:23:54:23:51"));
|
||||
uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n4, channelc0,
|
||||
uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, channelc0,
|
||||
Eui48Address("10:54:23:54:23:52"));
|
||||
uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n5, channelc0,
|
||||
uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, channelc0,
|
||||
Eui48Address("10:54:23:54:23:53"));
|
||||
|
||||
// Later, we add IP addresses.
|
||||
|
||||
@@ -157,8 +157,7 @@ int main (int argc, char *argv[])
|
||||
Ptr<PacketSink> sink = Create<PacketSink> (
|
||||
n3,
|
||||
InetSocketAddress (Ipv4Address::GetAny (), 80),
|
||||
"Udp",
|
||||
true);
|
||||
"Udp");
|
||||
// Start the sink
|
||||
sink->Start (Seconds (1.0));
|
||||
sink->Stop (Seconds (10.0));
|
||||
@@ -178,8 +177,7 @@ int main (int argc, char *argv[])
|
||||
sink = Create<PacketSink> (
|
||||
n1,
|
||||
InetSocketAddress (Ipv4Address::GetAny (), 80),
|
||||
"Udp",
|
||||
true);
|
||||
"Udp");
|
||||
// Start the sink
|
||||
sink->Start (Seconds (1.1));
|
||||
sink->Stop (Seconds (10.0));
|
||||
|
||||
@@ -38,11 +38,7 @@
|
||||
// - Tracing of queues and packet receptions to file
|
||||
// "simple-point-to-point.tr"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/default-value.h"
|
||||
#include "ns3/ptr.h"
|
||||
@@ -68,19 +64,34 @@
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
NS_DEBUG_COMPONENT_DEFINE ("Me");
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
// Users may find it convenient to turn on explicit debugging
|
||||
// for selected modules; the below lines suggest how to do this
|
||||
// remember to add #include "ns3/debug.h" before enabling these
|
||||
#if 0
|
||||
DebugComponentEnable("Me");
|
||||
DebugComponentEnable("Object");
|
||||
DebugComponentEnable("Queue");
|
||||
DebugComponentEnable("DropTailQueue");
|
||||
DebugComponentEnable("Channel");
|
||||
DebugComponentEnable("PointToPointChannel");
|
||||
DebugComponentEnable("PointToPointNetDevice");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("NetDevice");
|
||||
DebugComponentEnable("PacketSocket");
|
||||
DebugComponentEnable("OnOffApplication");
|
||||
DebugComponentEnable("UdpSocket");
|
||||
DebugComponentEnable("UdpL4Protocol");
|
||||
DebugComponentEnable("Ipv4L3Protocol");
|
||||
DebugComponentEnable("Ipv4StaticRouting");
|
||||
DebugComponentEnable("Ipv4Interface");
|
||||
DebugComponentEnable("ArpIpv4Interface");
|
||||
DebugComponentEnable("Ipv4LoopbackInterface");
|
||||
#endif
|
||||
|
||||
// Set up some default values for the simulation. Use the Bind()
|
||||
@@ -102,12 +113,14 @@ int main (int argc, char *argv[])
|
||||
|
||||
// Here, we will explicitly create four nodes. In more sophisticated
|
||||
// topologies, we could configure a node factory.
|
||||
NS_DEBUG("Create nodes.");
|
||||
Ptr<Node> n0 = Create<InternetNode> ();
|
||||
Ptr<Node> n1 = Create<InternetNode> ();
|
||||
Ptr<Node> n2 = Create<InternetNode> ();
|
||||
Ptr<Node> n3 = Create<InternetNode> ();
|
||||
|
||||
// We create the channels first without any IP addressing information
|
||||
NS_DEBUG("Create channels.");
|
||||
Ptr<PointToPointChannel> channel0 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n0, n2, DataRate(5000000), MilliSeconds(2));
|
||||
@@ -121,6 +134,7 @@ int main (int argc, char *argv[])
|
||||
n2, n3, DataRate(1500000), MilliSeconds(10));
|
||||
|
||||
// Later, we add IP addresses.
|
||||
NS_DEBUG("Assign IP Addresses.");
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel0, n0, Ipv4Address("10.1.1.1"),
|
||||
n2, Ipv4Address("10.1.1.2"));
|
||||
@@ -137,13 +151,14 @@ int main (int argc, char *argv[])
|
||||
// NetDevice creation, IP Address assignment, and routing) are
|
||||
// separated because there may be a need to postpone IP Address
|
||||
// assignment (emulation) or modify to use dynamic routing
|
||||
NS_DEBUG("Add Static Routes.");
|
||||
PointToPointTopology::AddIpv4Routes(n0, n2, channel0);
|
||||
PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
|
||||
PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
|
||||
|
||||
|
||||
// Create the OnOff application to send UDP datagrams of size
|
||||
// 210 bytes at a rate of 448 Kb/s
|
||||
NS_DEBUG("Create Applications.");
|
||||
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
|
||||
n0,
|
||||
InetSocketAddress ("10.1.3.2", 80),
|
||||
@@ -182,10 +197,10 @@ int main (int argc, char *argv[])
|
||||
// Start the sink
|
||||
sink->Start (Seconds (1.1));
|
||||
sink->Stop (Seconds (10.0));
|
||||
sink->SetQuiet (); // disable output from the Receive callback
|
||||
|
||||
// Here, finish off packet routing configuration
|
||||
// This will likely set by some global StaticRouting object in the future
|
||||
NS_DEBUG("Set Default Routes.");
|
||||
Ptr<Ipv4> ipv4;
|
||||
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
|
||||
@@ -194,6 +209,7 @@ int main (int argc, char *argv[])
|
||||
|
||||
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
|
||||
// Trace output will be sent to the simple-point-to-point.tr file
|
||||
NS_DEBUG("Configure Tracing.");
|
||||
AsciiTrace asciitrace ("simple-point-to-point.tr");
|
||||
asciitrace.TraceAllQueues ();
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
@@ -206,7 +222,8 @@ int main (int argc, char *argv[])
|
||||
PcapTrace pcaptrace ("simple-point-to-point.pcap");
|
||||
pcaptrace.TraceAllIp ();
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
NS_DEBUG("Run Simulation.");
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
NS_DEBUG("Done.");
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ def build(bld):
|
||||
['csma', 'internet-node'])
|
||||
obj.source = 'csma-packet-socket.cc'
|
||||
|
||||
obj = bld.create_ns3_program('csma-multicast',
|
||||
['csma', 'internet-node'])
|
||||
obj.source = 'csma-multicast.cc'
|
||||
|
||||
obj = bld.create_ns3_program( 'mixed-global-routing',
|
||||
['point-to-point', 'internet-node', 'global-routing' , 'csma-cd'])
|
||||
obj.source = 'mixed-global-routing.cc'
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
// George F. Riley, Georgia Tech, Spring 2007
|
||||
// Adapted from ApplicationOnOff in GTNetS.
|
||||
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/address.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/nstime.h"
|
||||
@@ -34,6 +35,8 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "onoff-application.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("OnOffApplication");
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace ns3 {
|
||||
@@ -95,30 +98,37 @@ OnOffApplication::Construct (Ptr<Node> n,
|
||||
m_iid = iid;
|
||||
}
|
||||
|
||||
|
||||
OnOffApplication::~OnOffApplication()
|
||||
{}
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::~OnOffApplication()");
|
||||
}
|
||||
|
||||
void
|
||||
OnOffApplication::SetMaxBytes(uint32_t maxBytes)
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::SetMaxBytes(" << maxBytes << ")");
|
||||
m_maxBytes = maxBytes;
|
||||
}
|
||||
|
||||
void
|
||||
OnOffApplication::SetDefaultRate (const DataRate &rate)
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::SetDefaultRate(" << &rate << ")");
|
||||
g_defaultRate.SetValue (rate);
|
||||
}
|
||||
|
||||
void
|
||||
OnOffApplication::SetDefaultSize (uint32_t size)
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::SetDefaultSize(" << size << ")");
|
||||
g_defaultSize.SetValue (size);
|
||||
}
|
||||
|
||||
void
|
||||
OnOffApplication::DoDispose (void)
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::DoDispose()");
|
||||
|
||||
m_socket = 0;
|
||||
delete m_onTime;
|
||||
delete m_offTime;
|
||||
@@ -130,10 +140,11 @@ OnOffApplication::DoDispose (void)
|
||||
Application::DoDispose ();
|
||||
}
|
||||
|
||||
|
||||
// Application Methods
|
||||
void OnOffApplication::StartApplication() // Called at time specified by Start
|
||||
void OnOffApplication::StartApplication() // Called at time specified by Start
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::StartApplication()");
|
||||
|
||||
// Create the socket if not already
|
||||
if (!m_socket)
|
||||
{
|
||||
@@ -151,8 +162,10 @@ void OnOffApplication::StartApplication() // Called at time specified by Star
|
||||
ScheduleStartEvent();
|
||||
}
|
||||
|
||||
void OnOffApplication::StopApplication() // Called at time specified by Stop
|
||||
void OnOffApplication::StopApplication() // Called at time specified by Stop
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::StopApplication()");
|
||||
|
||||
if (m_sendEvent.IsRunning ())
|
||||
{ // Cancel the pending send packet event
|
||||
// Calculate residual bits since last packet sent
|
||||
@@ -166,23 +179,32 @@ void OnOffApplication::StopApplication() // Called at time specified by Stop
|
||||
// Event handlers
|
||||
void OnOffApplication::StartSending()
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::StartSending ()");
|
||||
|
||||
ScheduleNextTx(); // Schedule the send packet event
|
||||
}
|
||||
|
||||
void OnOffApplication::StopSending()
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::StopSending ()");
|
||||
|
||||
Simulator::Cancel(m_sendEvent);
|
||||
}
|
||||
|
||||
// Private helpers
|
||||
void OnOffApplication::ScheduleNextTx()
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::ScheduleNextTx ()");
|
||||
|
||||
if (m_totBytes < m_maxBytes)
|
||||
{
|
||||
uint32_t bits = m_pktSize * 8 - m_residualBits;
|
||||
NS_DEBUG("OnOffApplication::ScheduleNextTx (): bits = " << bits);
|
||||
Time nextTime(Seconds (bits /
|
||||
static_cast<double>(m_cbrRate.GetBitRate()))); // Time till next packet
|
||||
m_sendEvent = Simulator::Schedule(nextTime, &OnOffApplication::SendPacket, this);
|
||||
NS_DEBUG("OnOffApplication::ScheduleNextTx (): nextTime = " << nextTime);
|
||||
m_sendEvent = Simulator::Schedule(nextTime,
|
||||
&OnOffApplication::SendPacket, this);
|
||||
}
|
||||
else
|
||||
{ // All done, cancel any pending events
|
||||
@@ -192,12 +214,18 @@ void OnOffApplication::ScheduleNextTx()
|
||||
|
||||
void OnOffApplication::ScheduleStartEvent()
|
||||
{ // Schedules the event to start sending data (switch to the "On" state)
|
||||
NS_DEBUG("OnOffApplication::ScheduleStartEvent ()");
|
||||
|
||||
Time offInterval = Seconds(m_offTime->GetValue());
|
||||
NS_DEBUG("OnOffApplication::ScheduleStartEvent (): "
|
||||
"start at " << offInterval);
|
||||
m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this);
|
||||
}
|
||||
|
||||
void OnOffApplication::ScheduleStopEvent()
|
||||
{ // Schedules the event to stop sending data (switch to "Off" state)
|
||||
NS_DEBUG("OnOffApplication::ScheduleStopEvent ()");
|
||||
|
||||
Time onInterval = Seconds(m_onTime->GetValue());
|
||||
Simulator::Schedule(onInterval, &OnOffApplication::StopSending, this);
|
||||
}
|
||||
@@ -205,6 +233,8 @@ void OnOffApplication::ScheduleStopEvent()
|
||||
|
||||
void OnOffApplication::SendPacket()
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::SendPacket ()");
|
||||
|
||||
NS_ASSERT (m_sendEvent.IsExpired ());
|
||||
m_socket->Send(Packet (m_pktSize));
|
||||
m_totBytes += m_pktSize;
|
||||
@@ -215,6 +245,8 @@ void OnOffApplication::SendPacket()
|
||||
|
||||
void OnOffApplication::ConnectionSucceeded(Ptr<Socket>)
|
||||
{
|
||||
NS_DEBUG("OnOffApplication::ConnectionSucceeded ()");
|
||||
|
||||
m_connected = true;
|
||||
ScheduleStartEvent();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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: Tom Henderson (tomhend@u.washington.edu)
|
||||
*/
|
||||
#include "ns3/address.h"
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
@@ -35,34 +37,25 @@ NS_DEBUG_COMPONENT_DEFINE ("PacketSink");
|
||||
|
||||
PacketSink::PacketSink (Ptr<Node> n,
|
||||
const Address &local,
|
||||
std::string iid,
|
||||
bool quiet)
|
||||
std::string iid)
|
||||
: Application(n)
|
||||
{
|
||||
Construct (n, local, iid, quiet);
|
||||
Construct (n, local, iid);
|
||||
}
|
||||
|
||||
void
|
||||
PacketSink::Construct (Ptr<Node> n,
|
||||
const Address &local,
|
||||
std::string iid,
|
||||
bool quiet)
|
||||
std::string iid)
|
||||
{
|
||||
m_socket = 0;
|
||||
m_local = local;
|
||||
m_iid = iid;
|
||||
m_quiet = quiet;
|
||||
}
|
||||
|
||||
PacketSink::~PacketSink()
|
||||
{}
|
||||
|
||||
void
|
||||
PacketSink::SetQuiet()
|
||||
{
|
||||
m_quiet = true;
|
||||
}
|
||||
|
||||
void
|
||||
PacketSink::DoDispose (void)
|
||||
{
|
||||
@@ -99,19 +92,17 @@ void PacketSink::StopApplication() // Called at time specified by Stop
|
||||
}
|
||||
}
|
||||
|
||||
// This callback body suggested by Joe Kopena's wiki
|
||||
// This LOG output inspired by the application on Joseph Kopena's wiki
|
||||
void PacketSink::Receive(Ptr<Socket> socket, const Packet &packet,
|
||||
const Address &from)
|
||||
{
|
||||
if (!m_quiet)
|
||||
if (InetSocketAddress::IsMatchingType (from))
|
||||
{
|
||||
if (InetSocketAddress::IsMatchingType (from))
|
||||
{
|
||||
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
|
||||
NS_DEBUG ( __PRETTY_FUNCTION__ << ": Received " <<
|
||||
packet.GetSize() << " bytes from " << address.GetIpv4() << " ["
|
||||
<< address << "]---'" << packet.PeekData() << "'");
|
||||
}
|
||||
InetSocketAddress address = InetSocketAddress::ConvertFrom (from);
|
||||
NS_DEBUG ( __PRETTY_FUNCTION__ << ": Received " <<
|
||||
packet.GetSize() << " bytes from " << address.GetIpv4() << " ["
|
||||
<< address << "]---'" << packet.PeekData() << "'");
|
||||
// TODO: Add a tracing source here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
//
|
||||
// Copyright (c) 2006 Georgia Tech Research Corporation
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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: Tom Henderson (tomhend@u.washington.edu)
|
||||
*/
|
||||
|
||||
#ifndef __packet_sink_h__
|
||||
#define __packet_sink_h__
|
||||
@@ -33,34 +34,34 @@ class Packet;
|
||||
/**
|
||||
* \brief Receive and consume traffic generated to an IP address and port
|
||||
*
|
||||
* This Application can be used as a receiver for packets generated by
|
||||
* traffic sourcing applications such as OnOffApplication. The constructor
|
||||
* specifies the Address (IP address and port) and the transport protocol
|
||||
* to use. A virtual Receive () method is installed as a callback on
|
||||
* the receiving socket. By default, it prints out the size of packets
|
||||
* and their address.
|
||||
* This application was written to complement OnOffApplication, but it
|
||||
* is more general so a PacketSink name was selected. Functionally it is
|
||||
* important to use in multicast situations, so that reception of the layer-2
|
||||
* multicast frames of interest are enabled, but it is also useful for
|
||||
* unicast as an example of how you can write something simple to receive
|
||||
* packets at the application layer. Also, if an IP stack generates
|
||||
* ICMP Port Unreachable errors, receiving applications will be needed.
|
||||
*
|
||||
* The constructor specifies the Address (IP address and port) and the
|
||||
* transport protocol to use. A virtual Receive () method is installed
|
||||
* as a callback on the receiving socket. By default, when logging is
|
||||
* enabled, it prints out the size of packets and their address, but
|
||||
* we intend to also add a tracing source to Receive() at a later date.
|
||||
*/
|
||||
class PacketSink : public Application
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \param n node associated to this application
|
||||
* \param local local ip address
|
||||
* \param iid
|
||||
* \param ontime on time random variable
|
||||
* \param offtime off time random variable
|
||||
* \param local local address to bind to
|
||||
* \param iid string to identify transport protocol of interest
|
||||
*/
|
||||
PacketSink (Ptr<Node> n,
|
||||
const Address &local,
|
||||
std::string iid, bool quiet=false);
|
||||
std::string iid);
|
||||
|
||||
virtual ~PacketSink ();
|
||||
|
||||
/**
|
||||
* \brief Turn off the logging output for the receive callback
|
||||
*/
|
||||
void SetQuiet (void);
|
||||
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
private:
|
||||
@@ -70,15 +71,13 @@ private:
|
||||
|
||||
void Construct (Ptr<Node> n,
|
||||
const Address &local,
|
||||
std::string iid,
|
||||
bool quiet);
|
||||
std::string iid);
|
||||
|
||||
virtual void Receive (Ptr<Socket> socket, const Packet& packet, const Address& from);
|
||||
|
||||
Ptr<Socket> m_socket; // Associated socket
|
||||
Address m_local; // Local address to bind to
|
||||
std::string m_iid; // Protocol name (e.g., "Udp")
|
||||
bool m_quiet; // Governs whether receive callback is quiet
|
||||
|
||||
};
|
||||
|
||||
|
||||
1084
src/common/buffer.cc
1084
src/common/buffer.cc
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005,2006 INRIA
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2005,2006,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
|
||||
@@ -24,6 +23,16 @@
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
#define BUFFER_HEURISTICS 1
|
||||
#define BUFFER_USE_INLINE 1
|
||||
|
||||
|
||||
#ifdef BUFFER_USE_INLINE
|
||||
#define BUFFER_INLINE inline
|
||||
#else
|
||||
#define BUFFER_INLINE
|
||||
#endif
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
@@ -36,6 +45,51 @@ namespace ns3 {
|
||||
* by creating new Buffers of the maximum size ever used.
|
||||
* The correct maximum size is learned at runtime during use by
|
||||
* recording the maximum size of each packet.
|
||||
*
|
||||
* \internal
|
||||
* The implementation of the Buffer class uses a COW (Copy On Write)
|
||||
* technique to ensure that the underlying data buffer which holds
|
||||
* the data bytes is shared among a lot of Buffer instances despite
|
||||
* data being added or removed from them.
|
||||
*
|
||||
* When multiple Buffer instances hold a reference to the same
|
||||
* underlying BufferData object, they must be able to detect when
|
||||
* the operation they want to perform should trigger a copy of the
|
||||
* BufferData. If the BufferData::m_count field is one, it means that
|
||||
* there exist only one instance of Buffer which references the
|
||||
* BufferData instance so, it is safe to modify it. It is also
|
||||
* safe to modify the content of a BufferData if the modification
|
||||
* falls outside of the "dirty area" defined by the BufferData.
|
||||
* In every other case, the BufferData must be copied before
|
||||
* being modified.
|
||||
*
|
||||
* To understand the way the Buffer::Add and Buffer::Remove methods
|
||||
* work, you first need to understand the "virtual offsets" used to
|
||||
* keep track of the content of buffers. Each Buffer instance
|
||||
* contains real data bytes in its BufferData instance but it also
|
||||
* contains "virtual zero data" which typically is used to represent
|
||||
* application-level payload. No memory is allocated to store the
|
||||
* zero bytes of application-level payload unless the user fragments
|
||||
* a Buffer: this application-level payload is kept track of with
|
||||
* a pair of integers which describe where in the buffer content
|
||||
* the "virtual zero area" starts and ends.
|
||||
*
|
||||
* ***: unused bytes
|
||||
* xxx: bytes "added" at the front of the zero area
|
||||
* ...: bytes "added" at the back of the zero area
|
||||
* 000: virtual zero bytes
|
||||
*
|
||||
* Real byte buffer: |********xxxxxxxxxxxx.........*****|
|
||||
* |--------^ m_start
|
||||
* |-------------------^ m_zeroAreaStart
|
||||
* |-----------------------------^ m_end - (m_zeroAreaEnd - m_zeroAreaStart)
|
||||
* virtual byte buffer: |xxxxxxxxxxxx0000000000000.........|
|
||||
* |--------^ m_start
|
||||
* |--------------------^ m_zeroAreaStart
|
||||
* |---------------------------------^ m_zeroAreaEnd
|
||||
* |------------------------------------------^ m_end
|
||||
*
|
||||
* A simple state invariant is that m_start <= m_zeroStart <= m_zeroEnd <= m_end
|
||||
*/
|
||||
class Buffer {
|
||||
public:
|
||||
@@ -44,23 +98,23 @@ public:
|
||||
*/
|
||||
class Iterator {
|
||||
public:
|
||||
inline Iterator ();
|
||||
Iterator ();
|
||||
/**
|
||||
* go forward by one byte
|
||||
*/
|
||||
inline void Next (void);
|
||||
void Next (void);
|
||||
/**
|
||||
* go backward by one byte
|
||||
*/
|
||||
inline void Prev (void);
|
||||
void Prev (void);
|
||||
/**
|
||||
* \param delta number of bytes to go forward
|
||||
*/
|
||||
inline void Next (uint32_t delta);
|
||||
void Next (uint32_t delta);
|
||||
/**
|
||||
* \param delta number of bytes to go backward
|
||||
*/
|
||||
inline void Prev (uint32_t delta);
|
||||
void Prev (uint32_t delta);
|
||||
/**
|
||||
* \param o the second iterator
|
||||
* \return number of bytes included between the two iterators
|
||||
@@ -69,18 +123,18 @@ public:
|
||||
* to the same underlying buffer. Debug builds ensure
|
||||
* this with an assert.
|
||||
*/
|
||||
inline uint32_t GetDistanceFrom (Iterator const &o) const;
|
||||
uint32_t GetDistanceFrom (Iterator const &o) const;
|
||||
|
||||
/**
|
||||
* \return true if this iterator points to the end of the byte array.
|
||||
* false otherwise.
|
||||
*/
|
||||
inline bool IsEnd (void) const;
|
||||
bool IsEnd (void) const;
|
||||
/**
|
||||
* \return true if this iterator points to the start of the byte array.
|
||||
* false otherwise.
|
||||
*/
|
||||
inline bool IsStart (void) const;
|
||||
bool IsStart (void) const;
|
||||
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
@@ -88,7 +142,7 @@ public:
|
||||
* Write the data in buffer and avance the iterator position
|
||||
* by one byte.
|
||||
*/
|
||||
inline void WriteU8 (uint8_t data);
|
||||
BUFFER_INLINE void WriteU8 (uint8_t data);
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
* \param len number of times data must be written in buffer
|
||||
@@ -96,7 +150,7 @@ public:
|
||||
* Write the data in buffer len times and avance the iterator position
|
||||
* by len byte.
|
||||
*/
|
||||
inline void WriteU8 (uint8_t data, uint32_t len);
|
||||
BUFFER_INLINE void WriteU8 (uint8_t data, uint32_t len);
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
*
|
||||
@@ -106,7 +160,7 @@ public:
|
||||
* return exactly what we wrote with writeU16 if the program
|
||||
* is run on the same machine.
|
||||
*/
|
||||
inline void WriteU16 (uint16_t data);
|
||||
void WriteU16 (uint16_t data);
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
*
|
||||
@@ -116,7 +170,7 @@ public:
|
||||
* return exactly what we wrote with writeU32 if the program
|
||||
* is run on the same machine.
|
||||
*/
|
||||
inline void WriteU32 (uint32_t data);
|
||||
void WriteU32 (uint32_t data);
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
*
|
||||
@@ -126,7 +180,7 @@ public:
|
||||
* return exactly what we wrote with writeU64 if the program
|
||||
* is run on the same machine.
|
||||
*/
|
||||
inline void WriteU64 (uint64_t data);
|
||||
void WriteU64 (uint64_t data);
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
*
|
||||
@@ -134,7 +188,7 @@ public:
|
||||
* by two bytes. The data is written in network order and the
|
||||
* input data is expected to be in host order.
|
||||
*/
|
||||
inline void WriteHtonU16 (uint16_t data);
|
||||
void WriteHtonU16 (uint16_t data);
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
*
|
||||
@@ -142,7 +196,7 @@ public:
|
||||
* by four bytes. The data is written in network order and the
|
||||
* input data is expected to be in host order.
|
||||
*/
|
||||
inline void WriteHtonU32 (uint32_t data);
|
||||
void WriteHtonU32 (uint32_t data);
|
||||
/**
|
||||
* \param data data to write in buffer
|
||||
*
|
||||
@@ -150,7 +204,7 @@ public:
|
||||
* by eight bytes. The data is written in network order and the
|
||||
* input data is expected to be in host order.
|
||||
*/
|
||||
inline void WriteHtonU64 (uint64_t data);
|
||||
void WriteHtonU64 (uint64_t data);
|
||||
/**
|
||||
* \param buffer a byte buffer to copy in the internal buffer.
|
||||
* \param size number of bytes to copy.
|
||||
@@ -158,7 +212,7 @@ public:
|
||||
* Write the data in buffer and avance the iterator position
|
||||
* by size bytes.
|
||||
*/
|
||||
inline void Write (uint8_t const*buffer, uint32_t size);
|
||||
void Write (uint8_t const*buffer, uint32_t size);
|
||||
/**
|
||||
* \param start the start of the data to copy
|
||||
* \param end the end of the data to copy
|
||||
@@ -170,7 +224,7 @@ public:
|
||||
* we do to avoid overlapping copies. This is enforced
|
||||
* in debug builds by asserts.
|
||||
*/
|
||||
inline void Write (Iterator start, Iterator end);
|
||||
void Write (Iterator start, Iterator end);
|
||||
|
||||
/**
|
||||
* \return the byte read in the buffer.
|
||||
@@ -178,7 +232,7 @@ public:
|
||||
* Read data and advance the Iterator by the number of bytes
|
||||
* read.
|
||||
*/
|
||||
inline uint8_t ReadU8 (void);
|
||||
BUFFER_INLINE uint8_t ReadU8 (void);
|
||||
/**
|
||||
* \return the two bytes read in the buffer.
|
||||
*
|
||||
@@ -186,7 +240,7 @@ public:
|
||||
* read.
|
||||
* The data is read in the format written by writeU16.
|
||||
*/
|
||||
inline uint16_t ReadU16 (void);
|
||||
uint16_t ReadU16 (void);
|
||||
/**
|
||||
* \return the four bytes read in the buffer.
|
||||
*
|
||||
@@ -194,7 +248,7 @@ public:
|
||||
* read.
|
||||
* The data is read in the format written by writeU32.
|
||||
*/
|
||||
inline uint32_t ReadU32 (void);
|
||||
uint32_t ReadU32 (void);
|
||||
/**
|
||||
* \return the eight bytes read in the buffer.
|
||||
*
|
||||
@@ -202,7 +256,7 @@ public:
|
||||
* read.
|
||||
* The data is read in the format written by writeU64.
|
||||
*/
|
||||
inline uint64_t ReadU64 (void);
|
||||
uint64_t ReadU64 (void);
|
||||
/**
|
||||
* \return the two bytes read in the buffer.
|
||||
*
|
||||
@@ -210,7 +264,7 @@ public:
|
||||
* read.
|
||||
* The data is read in network format and return in host format.
|
||||
*/
|
||||
inline uint16_t ReadNtohU16 (void);
|
||||
uint16_t ReadNtohU16 (void);
|
||||
/**
|
||||
* \return the four bytes read in the buffer.
|
||||
*
|
||||
@@ -218,7 +272,7 @@ public:
|
||||
* read.
|
||||
* The data is read in network format and return in host format.
|
||||
*/
|
||||
inline uint32_t ReadNtohU32 (void);
|
||||
uint32_t ReadNtohU32 (void);
|
||||
/**
|
||||
* \return the eight bytes read in the buffer.
|
||||
*
|
||||
@@ -226,7 +280,7 @@ public:
|
||||
* read.
|
||||
* The data is read in network format and return in host format.
|
||||
*/
|
||||
inline uint64_t ReadNtohU64 (void);
|
||||
uint64_t ReadNtohU64 (void);
|
||||
/**
|
||||
* \param buffer buffer to copy data into
|
||||
* \param size number of bytes to copy
|
||||
@@ -235,22 +289,45 @@ public:
|
||||
* input buffer and avance the Iterator by the number of
|
||||
* bytes read.
|
||||
*/
|
||||
inline void Read (uint8_t *buffer, uint16_t size);
|
||||
void Read (uint8_t *buffer, uint32_t size);
|
||||
private:
|
||||
friend class Buffer;
|
||||
inline Iterator (Buffer const*buffer, uint32_t m_current);
|
||||
inline uint32_t GetIndex (uint32_t n);
|
||||
Iterator (Buffer const*buffer);
|
||||
Iterator (Buffer const*buffer, bool);
|
||||
void Construct (const Buffer *buffer);
|
||||
bool CheckNoZero (uint32_t start, uint32_t end) const;
|
||||
bool Check (uint32_t i) const;
|
||||
|
||||
/* offset in virtual bytes from the start of the data buffer to the
|
||||
* start of the "virtual zero area".
|
||||
*/
|
||||
uint32_t m_zeroStart;
|
||||
/* offset in virtual bytes from the start of the data buffer to the
|
||||
* end of the "virtual zero area".
|
||||
*/
|
||||
uint32_t m_zeroEnd;
|
||||
/* offset in virtual bytes from the start of the data buffer to the
|
||||
* start of the data which can be read by this iterator
|
||||
*/
|
||||
uint32_t m_dataStart;
|
||||
/* offset in virtual bytes from the start of the data buffer to the
|
||||
* end of the data which can be read by this iterator
|
||||
*/
|
||||
uint32_t m_dataEnd;
|
||||
/* offset in virtual bytes from the start of the data buffer to the
|
||||
* current position represented by this iterator.
|
||||
*/
|
||||
uint32_t m_current;
|
||||
/* a pointer to the underlying byte buffer. All offsets are relative
|
||||
* to this pointer.
|
||||
*/
|
||||
uint8_t *m_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* \return the number of bytes stored in this buffer.
|
||||
*/
|
||||
inline uint32_t GetSize (void) const;
|
||||
uint32_t GetSize (void) const;
|
||||
|
||||
/**
|
||||
* \return a pointer to the start of the internal
|
||||
@@ -313,409 +390,135 @@ public:
|
||||
* \return an Iterator which points to the
|
||||
* start of this Buffer.
|
||||
*/
|
||||
inline Buffer::Iterator Begin (void) const;
|
||||
Buffer::Iterator Begin (void) const;
|
||||
/**
|
||||
* \return an Iterator which points to the
|
||||
* end of this Buffer.
|
||||
*/
|
||||
inline Buffer::Iterator End (void) const;
|
||||
Buffer::Iterator End (void) const;
|
||||
|
||||
Buffer CreateFullCopy (void) const;
|
||||
|
||||
inline Buffer (Buffer const &o);
|
||||
inline Buffer &operator = (Buffer const &o);
|
||||
inline Buffer ();
|
||||
inline Buffer (uint32_t dataSize);
|
||||
inline ~Buffer ();
|
||||
Buffer (Buffer const &o);
|
||||
Buffer &operator = (Buffer const &o);
|
||||
Buffer ();
|
||||
Buffer (uint32_t dataSize);
|
||||
~Buffer ();
|
||||
private:
|
||||
struct BufferData {
|
||||
uint32_t m_count;
|
||||
uint32_t m_size;
|
||||
uint32_t m_initialStart;
|
||||
uint32_t m_dirtyStart;
|
||||
uint32_t m_dirtySize;
|
||||
uint8_t m_data[1];
|
||||
};
|
||||
class BufferDataList : public std::vector<struct Buffer::BufferData*>
|
||||
{
|
||||
public:
|
||||
~BufferDataList ();
|
||||
};
|
||||
|
||||
inline uint8_t *GetStart (void) const;
|
||||
void TransformIntoRealBuffer (void) const;
|
||||
static void Recycle (struct Buffer::BufferData *data);
|
||||
static struct Buffer::BufferData *Create (void);
|
||||
static struct Buffer::BufferData *Allocate (uint32_t size, uint32_t start);
|
||||
static void Deallocate (struct Buffer::BufferData *data);
|
||||
|
||||
static BufferDataList m_freeList;
|
||||
static uint32_t m_maxTotalAddStart;
|
||||
static uint32_t m_maxTotalAddEnd;
|
||||
bool CheckInternalState (void) const;
|
||||
void Initialize (uint32_t zeroSize);
|
||||
uint32_t GetInternalSize (void) const;
|
||||
uint32_t GetInternalEnd (void) const;
|
||||
static void Recycle (struct BufferData *data);
|
||||
static struct BufferData *Create (uint32_t size);
|
||||
|
||||
/* This structure is described in the buffer.cc file.
|
||||
*/
|
||||
struct BufferData *m_data;
|
||||
uint32_t m_zeroAreaSize;
|
||||
#ifdef BUFFER_HEURISTICS
|
||||
/* keep track of the maximum value of m_zeroAreaStart across
|
||||
* the lifetime of a Buffer instance. This variable is used
|
||||
* purely as a source of information for the heuristics which
|
||||
* decide on the position of the zero area in new buffers.
|
||||
* It is read from the Buffer destructor to update the global
|
||||
* heuristic data and these global heuristic data are used from
|
||||
* the Buffer constructor to choose an initial value for
|
||||
* m_zeroAreaStart.
|
||||
* It is possible to disable all these heuristics by undefining the
|
||||
* BUFFER_HEURISTICS macro at the top of buffer.h
|
||||
*/
|
||||
uint32_t m_maxZeroAreaStart;
|
||||
#endif /* BUFFER_HEURISTICS */
|
||||
/* offset to the start of the virtual zero area from the start
|
||||
* of m_data->m_data
|
||||
*/
|
||||
uint32_t m_zeroAreaStart;
|
||||
/* offset to the end of the virtual zero area from the start
|
||||
* of m_data->m_data
|
||||
*/
|
||||
uint32_t m_zeroAreaEnd;
|
||||
/* offset to the start of the data referenced by this Buffer
|
||||
* instance from the start of m_data->m_data
|
||||
*/
|
||||
uint32_t m_start;
|
||||
uint32_t m_size;
|
||||
/* offset to the end of the data referenced by this Buffer
|
||||
* instance from the start of m_data->m_data
|
||||
*/
|
||||
uint32_t m_end;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
/**************************************************
|
||||
Start of implementation of methods which
|
||||
need to be inline for performance reasons.
|
||||
*************************************************/
|
||||
#ifdef BUFFER_USE_INLINE
|
||||
|
||||
#include "ns3/assert.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Buffer::Buffer ()
|
||||
: m_data (Buffer::Create ()),
|
||||
m_zeroAreaSize (0),
|
||||
m_start (m_maxTotalAddStart),
|
||||
m_size (0)
|
||||
void
|
||||
Buffer::Iterator::WriteU8 (uint8_t data)
|
||||
{
|
||||
if (m_start > m_data->m_size)
|
||||
NS_ASSERT (Check (m_current));
|
||||
|
||||
if (m_current < m_zeroStart)
|
||||
{
|
||||
m_start = 0;
|
||||
}
|
||||
NS_ASSERT (m_start <= m_data->m_size);
|
||||
}
|
||||
|
||||
Buffer::Buffer (uint32_t dataSize)
|
||||
: m_data (Buffer::Create ()),
|
||||
m_zeroAreaSize (dataSize),
|
||||
m_start (m_maxTotalAddStart),
|
||||
m_size (0)
|
||||
{
|
||||
if (m_start > m_data->m_size)
|
||||
{
|
||||
m_start = 0;
|
||||
}
|
||||
NS_ASSERT (m_start <= m_data->m_size);
|
||||
}
|
||||
|
||||
|
||||
Buffer::Buffer (Buffer const&o)
|
||||
: m_data (o.m_data),
|
||||
m_zeroAreaSize (o.m_zeroAreaSize),
|
||||
m_start (o.m_start),
|
||||
m_size (o.m_size)
|
||||
{
|
||||
m_data->m_count++;
|
||||
NS_ASSERT (m_start <= m_data->m_size);
|
||||
}
|
||||
|
||||
Buffer &
|
||||
Buffer::operator = (Buffer const&o)
|
||||
{
|
||||
if (m_data != o.m_data)
|
||||
{
|
||||
// not assignment to self.
|
||||
m_data->m_count--;
|
||||
if (m_data->m_count == 0)
|
||||
{
|
||||
Recycle (m_data);
|
||||
}
|
||||
m_data = o.m_data;
|
||||
m_data->m_count++;
|
||||
}
|
||||
m_zeroAreaSize = o.m_zeroAreaSize;
|
||||
m_start = o.m_start;
|
||||
m_size = o.m_size;
|
||||
NS_ASSERT (m_start <= m_data->m_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Buffer::~Buffer ()
|
||||
{
|
||||
m_data->m_count--;
|
||||
if (m_data->m_count == 0)
|
||||
{
|
||||
Recycle (m_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t *
|
||||
Buffer::GetStart (void) const
|
||||
{
|
||||
return m_data->m_data + m_start;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Buffer::GetSize (void) const
|
||||
{
|
||||
return m_size + m_zeroAreaSize;
|
||||
}
|
||||
|
||||
Buffer::Iterator
|
||||
Buffer::Begin (void) const
|
||||
{
|
||||
return Buffer::Iterator (this, 0);
|
||||
}
|
||||
Buffer::Iterator
|
||||
Buffer::End (void) const
|
||||
{
|
||||
return Buffer::Iterator (this, GetSize ());
|
||||
}
|
||||
|
||||
|
||||
Buffer::Iterator::Iterator ()
|
||||
: m_zeroStart (0),
|
||||
m_zeroEnd (0),
|
||||
m_dataEnd (0),
|
||||
m_current (0),
|
||||
m_data (0)
|
||||
{}
|
||||
Buffer::Iterator::Iterator (Buffer const*buffer, uint32_t current)
|
||||
: m_zeroStart (buffer->m_data->m_initialStart-buffer->m_start),
|
||||
m_zeroEnd (m_zeroStart+buffer->m_zeroAreaSize),
|
||||
m_dataEnd (buffer->GetSize ()),
|
||||
m_current (current),
|
||||
m_data (buffer->m_data->m_data+buffer->m_start)
|
||||
{}
|
||||
|
||||
void
|
||||
Buffer::Iterator::Next (void)
|
||||
{
|
||||
NS_ASSERT (m_current + 1 <= m_dataEnd);
|
||||
m_current++;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::Prev (void)
|
||||
{
|
||||
NS_ASSERT (m_current >= 1);
|
||||
m_current--;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::Next (uint32_t delta)
|
||||
{
|
||||
NS_ASSERT (m_current + delta <= m_dataEnd);
|
||||
m_current += delta;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::Prev (uint32_t delta)
|
||||
{
|
||||
NS_ASSERT (m_current >= delta);
|
||||
m_current -= delta;
|
||||
}
|
||||
uint32_t
|
||||
Buffer::Iterator::GetDistanceFrom (Iterator const &o) const
|
||||
{
|
||||
NS_ASSERT (m_data == o.m_data);
|
||||
int32_t start = m_current;
|
||||
int32_t end = o.m_current;
|
||||
int32_t diff = end - start;
|
||||
if (diff < 0)
|
||||
{
|
||||
return -diff;
|
||||
m_data[m_current] = data;
|
||||
m_current++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return diff;
|
||||
m_data[m_current - (m_zeroEnd-m_zeroStart)] = data;
|
||||
m_current++;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Buffer::Iterator::IsEnd (void) const
|
||||
{
|
||||
return m_current == m_dataEnd;
|
||||
}
|
||||
bool
|
||||
Buffer::Iterator::IsStart (void) const
|
||||
{
|
||||
return m_current == 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Buffer::Iterator::GetIndex (uint32_t n)
|
||||
{
|
||||
NS_ASSERT (
|
||||
(m_current + n <= m_dataEnd) &&
|
||||
((m_current + n <= m_zeroStart) ||
|
||||
(m_current >= m_zeroEnd) ||
|
||||
m_zeroStart == m_zeroEnd)
|
||||
);
|
||||
uint32_t index;
|
||||
if (m_current < m_zeroStart)
|
||||
{
|
||||
index = m_current;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = m_current - (m_zeroEnd-m_zeroStart);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Buffer::Iterator::Write (Iterator start, Iterator end)
|
||||
{
|
||||
NS_ASSERT (start.m_data == end.m_data);
|
||||
NS_ASSERT (start.m_current <= end.m_current);
|
||||
NS_ASSERT (start.m_zeroStart == end.m_zeroStart);
|
||||
NS_ASSERT (start.m_zeroEnd == end.m_zeroEnd);
|
||||
NS_ASSERT (m_data != start.m_data);
|
||||
uint32_t size = end.m_current - start.m_current;
|
||||
uint8_t *src = start.m_data + start.GetIndex (size);
|
||||
uint8_t *dest = m_data + GetIndex (size);
|
||||
memcpy (dest, src, size);
|
||||
m_current += size;
|
||||
}
|
||||
|
||||
void
|
||||
Buffer::Iterator::WriteU8 (uint8_t data, uint32_t len)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (len);
|
||||
memset (current, data, len);
|
||||
m_current += len;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::WriteU8 (uint8_t data)
|
||||
{
|
||||
m_data[GetIndex (1)] = data;
|
||||
m_current++;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::WriteU16 (uint16_t data)
|
||||
{
|
||||
uint16_t *buffer = (uint16_t *)(m_data + GetIndex (2));
|
||||
*buffer = data;
|
||||
m_current += 2;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::WriteU32 (uint32_t data)
|
||||
{
|
||||
uint32_t *buffer = (uint32_t *)(m_data + GetIndex (4));
|
||||
*buffer = data;
|
||||
m_current += 4;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::WriteU64 (uint64_t data)
|
||||
{
|
||||
uint64_t *buffer = (uint64_t *)(m_data + GetIndex (8));
|
||||
*buffer = data;
|
||||
m_current += 8;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::WriteHtonU16 (uint16_t data)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (2);
|
||||
*(current+0) = (data >> 8) & 0xff;
|
||||
*(current+1) = (data >> 0) & 0xff;
|
||||
m_current += 2;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::WriteHtonU32 (uint32_t data)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (4);
|
||||
*(current+0) = (data >> 24) & 0xff;
|
||||
*(current+1) = (data >> 16) & 0xff;
|
||||
*(current+2) = (data >> 8) & 0xff;
|
||||
*(current+3) = (data >> 0) & 0xff;
|
||||
m_current += 4;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::WriteHtonU64 (uint64_t data)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (8);
|
||||
*(current+0) = (data >> 56) & 0xff;
|
||||
*(current+1) = (data >> 48) & 0xff;
|
||||
*(current+2) = (data >> 40) & 0xff;
|
||||
*(current+3) = (data >> 32) & 0xff;
|
||||
*(current+4) = (data >> 24) & 0xff;
|
||||
*(current+5) = (data >> 16) & 0xff;
|
||||
*(current+6) = (data >> 8) & 0xff;
|
||||
*(current+7) = (data >> 0) & 0xff;
|
||||
m_current += 8;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::Write (uint8_t const*buffer, uint32_t size)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (size);
|
||||
memcpy (current, buffer, size);
|
||||
m_current += size;
|
||||
NS_ASSERT (CheckNoZero (m_current, m_current + len));
|
||||
if (m_current <= m_zeroStart)
|
||||
{
|
||||
memset (&(m_data[m_current]), data, len);
|
||||
m_current += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *buffer = &m_data[m_current - (m_zeroEnd-m_zeroStart)];
|
||||
memset (buffer, data, len);
|
||||
m_current += len;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
Buffer::Iterator::ReadU8 (void)
|
||||
{
|
||||
uint8_t data = m_data[GetIndex(1)];
|
||||
m_current++;
|
||||
return data;
|
||||
}
|
||||
uint16_t
|
||||
Buffer::Iterator::ReadU16 (void)
|
||||
{
|
||||
uint16_t *buffer = reinterpret_cast<uint16_t *>(m_data + GetIndex (2));
|
||||
m_current += 2;
|
||||
return *buffer;
|
||||
}
|
||||
uint32_t
|
||||
Buffer::Iterator::ReadU32 (void)
|
||||
{
|
||||
uint32_t *buffer = reinterpret_cast<uint32_t *>(m_data + GetIndex (4));
|
||||
m_current += 4;
|
||||
return *buffer;
|
||||
}
|
||||
uint64_t
|
||||
Buffer::Iterator::ReadU64 (void)
|
||||
{
|
||||
uint64_t *buffer = reinterpret_cast<uint64_t *>(m_data + GetIndex (8));
|
||||
m_current += 8;
|
||||
return *buffer;
|
||||
}
|
||||
uint16_t
|
||||
Buffer::Iterator::ReadNtohU16 (void)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (2);
|
||||
uint16_t retval = 0;
|
||||
retval |= static_cast<uint16_t> (current[0]) << 8;
|
||||
retval |= static_cast<uint16_t> (current[1]) << 0;
|
||||
m_current += 2;
|
||||
return retval;
|
||||
}
|
||||
uint32_t
|
||||
Buffer::Iterator::ReadNtohU32 (void)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (4);
|
||||
uint32_t retval = 0;
|
||||
retval |= static_cast<uint32_t> (current[0]) << 24;
|
||||
retval |= static_cast<uint32_t> (current[1]) << 16;
|
||||
retval |= static_cast<uint32_t> (current[2]) << 8;
|
||||
retval |= static_cast<uint32_t> (current[3]) << 0;
|
||||
m_current += 4;
|
||||
return retval;
|
||||
}
|
||||
uint64_t
|
||||
Buffer::Iterator::ReadNtohU64 (void)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (8);
|
||||
uint64_t retval = 0;
|
||||
retval |= static_cast<uint64_t> (current[0]) << 56;
|
||||
retval |= static_cast<uint64_t> (current[1]) << 48;
|
||||
retval |= static_cast<uint64_t> (current[2]) << 40;
|
||||
retval |= static_cast<uint64_t> (current[3]) << 32;
|
||||
retval |= static_cast<uint64_t> (current[4]) << 24;
|
||||
retval |= static_cast<uint64_t> (current[5]) << 16;
|
||||
retval |= static_cast<uint64_t> (current[6]) << 8;
|
||||
retval |= static_cast<uint64_t> (current[7]) << 0;
|
||||
m_current += 8;
|
||||
return retval;
|
||||
}
|
||||
void
|
||||
Buffer::Iterator::Read (uint8_t *buffer, uint16_t size)
|
||||
{
|
||||
uint8_t *current = m_data + GetIndex (size);
|
||||
memcpy (buffer, current, size);
|
||||
m_current += size;
|
||||
NS_ASSERT (m_current >= m_dataStart &&
|
||||
m_current <= m_dataEnd);
|
||||
|
||||
if (m_current < m_zeroStart)
|
||||
{
|
||||
uint8_t data = m_data[m_current];
|
||||
m_current++;
|
||||
return data;
|
||||
}
|
||||
else if (m_current < m_zeroEnd)
|
||||
{
|
||||
m_current++;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t data = m_data[m_current - (m_zeroEnd-m_zeroStart)];
|
||||
m_current++;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* BUFFER_USE_INLINE */
|
||||
|
||||
#endif /* BUFFER_H */
|
||||
|
||||
@@ -673,6 +673,13 @@ PacketMetadataTest::RunTests (void)
|
||||
p = DoAddHeader (p);
|
||||
CHECK_HISTORY (p, 2, 10, 10);
|
||||
|
||||
p = Packet (10);
|
||||
ADD_HEADER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
p.RemoveAtStart (8+10+8);
|
||||
CHECK_HISTORY (p, 1, 8);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ PacketTest::RunTests (void)
|
||||
packet.GetSize ());
|
||||
if (msg != "hello world")
|
||||
{
|
||||
Failure () << "expected size 'hello world', got " << msg << std::endl;
|
||||
Failure () << "expected 'hello world', got '" << msg << "'" << std::endl;
|
||||
ok = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ CsmaChannel::TransmitEnd()
|
||||
}
|
||||
|
||||
NS_DEBUG ("CsmaChannel::TransmitEnd (): Schedule event in " <<
|
||||
m_delay.GetSeconds () << "sec");
|
||||
m_delay.GetSeconds () << " sec");
|
||||
|
||||
Simulator::Schedule (m_delay,
|
||||
&CsmaChannel::PropagationCompleteEvent,
|
||||
|
||||
@@ -35,82 +35,79 @@
|
||||
namespace ns3 {
|
||||
|
||||
uint32_t
|
||||
CsmaIpv4Topology::AddIpv4CsmaNode(Ptr<Node> n1,
|
||||
Ptr<CsmaChannel> ch,
|
||||
Eui48Address addr)
|
||||
CsmaIpv4Topology::AddIpv4CsmaNetDevice(
|
||||
Ptr<Node> node,
|
||||
Ptr<CsmaChannel> channel,
|
||||
Eui48Address addr)
|
||||
{
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
|
||||
// assume full-duplex
|
||||
Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
|
||||
ns3::CsmaNetDevice::IP_ARP,
|
||||
true, true);
|
||||
nd0->AddQueue(q);
|
||||
nd0->Attach (ch);
|
||||
return nd0->GetIfIndex ();
|
||||
Ptr<CsmaNetDevice> nd = Create<CsmaNetDevice> (node, addr,
|
||||
ns3::CsmaNetDevice::IP_ARP, true, true);
|
||||
|
||||
nd->AddQueue(q);
|
||||
nd->Attach (channel);
|
||||
return nd->GetIfIndex ();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CsmaIpv4Topology::AddIpv4LlcCsmaNode(Ptr<Node> n1,
|
||||
Ptr<CsmaChannel> ch,
|
||||
Eui48Address addr)
|
||||
Ptr<CsmaChannel> ch,
|
||||
Eui48Address addr)
|
||||
{
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
|
||||
Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
|
||||
ns3::CsmaNetDevice::LLC,
|
||||
true, false);
|
||||
ns3::CsmaNetDevice::LLC,
|
||||
true, false);
|
||||
nd0->AddQueue(q);
|
||||
nd0->Attach (ch);
|
||||
|
||||
Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
|
||||
ns3::CsmaNetDevice::LLC,
|
||||
false, true);
|
||||
ns3::CsmaNetDevice::LLC,
|
||||
false, true);
|
||||
nd1->AddQueue(q);
|
||||
nd1->Attach (ch);
|
||||
}
|
||||
|
||||
void
|
||||
CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr<Node> n1,
|
||||
Ptr<CsmaChannel> ch,
|
||||
Eui48Address addr)
|
||||
Ptr<CsmaChannel> ch,
|
||||
Eui48Address addr)
|
||||
{
|
||||
Ptr<Queue> q = Queue::CreateDefault ();
|
||||
|
||||
Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
|
||||
ns3::CsmaNetDevice::RAW,
|
||||
true, false);
|
||||
ns3::CsmaNetDevice::RAW,
|
||||
true, false);
|
||||
nd0->AddQueue(q);
|
||||
nd0->Attach (ch);
|
||||
|
||||
Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
|
||||
ns3::CsmaNetDevice::RAW,
|
||||
false, true);
|
||||
ns3::CsmaNetDevice::RAW,
|
||||
false, true);
|
||||
nd1->AddQueue(q);
|
||||
nd1->Attach (ch);
|
||||
}
|
||||
|
||||
void
|
||||
CsmaIpv4Topology::AddIpv4Address(Ptr<Node> n1,
|
||||
int ndNum,
|
||||
const Ipv4Address& addr1,
|
||||
const Ipv4Mask& netmask1)
|
||||
uint32_t
|
||||
CsmaIpv4Topology::AddIpv4Address(
|
||||
Ptr<Node> node,
|
||||
uint32_t netDeviceNumber,
|
||||
const Ipv4Address address,
|
||||
const Ipv4Mask mask)
|
||||
{
|
||||
Ptr<NetDevice> nd = node->GetDevice(netDeviceNumber);
|
||||
|
||||
// Duplex link is assumed to be subnetted as a /30
|
||||
// May run this unnumbered in the future?
|
||||
Ipv4Mask netmask(netmask1);
|
||||
|
||||
Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
|
||||
|
||||
Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
uint32_t index1 = ip1->AddInterface (nd1);
|
||||
|
||||
ip1->SetAddress (index1, addr1);
|
||||
ip1->SetNetworkMask (index1, netmask);
|
||||
ip1->SetUp (index1);
|
||||
Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
uint32_t ifIndex = ipv4->AddInterface (nd);
|
||||
|
||||
ipv4->SetAddress (ifIndex, address);
|
||||
ipv4->SetNetworkMask (ifIndex, mask);
|
||||
ipv4->SetUp (ifIndex);
|
||||
return ifIndex;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -133,7 +130,7 @@ CsmaIpv4Topology::AddIpv4Routes (
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
NS_ASSERT(found);
|
||||
NS_ASSERT (found);
|
||||
|
||||
uint32_t index2 = 0;
|
||||
found = false;
|
||||
@@ -145,7 +142,7 @@ CsmaIpv4Topology::AddIpv4Routes (
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
NS_ASSERT(found);
|
||||
NS_ASSERT (found);
|
||||
|
||||
ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
|
||||
ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2);
|
||||
|
||||
@@ -61,9 +61,9 @@ public:
|
||||
*
|
||||
* \return ifIndex of the device
|
||||
*/
|
||||
static uint32_t AddIpv4CsmaNode( Ptr<Node> n1,
|
||||
Ptr<CsmaChannel> ch,
|
||||
Eui48Address addr);
|
||||
static uint32_t AddIpv4CsmaNetDevice(Ptr<Node> node,
|
||||
Ptr<CsmaChannel> channel,
|
||||
Eui48Address addr);
|
||||
|
||||
/**
|
||||
* \param n1 Node to be attached to the Csma channel
|
||||
@@ -94,18 +94,23 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
* \param n1 Node
|
||||
* \param ndNum NetDevice number with which to associate address
|
||||
* \param addr1 Ipv4 Address for ndNum of n1
|
||||
* \param netmask1 network mask for ndNum of node n1
|
||||
* \brief Create an Ipv4 interface for a net device and assign an
|
||||
* Ipv4Address to that interface.
|
||||
*
|
||||
* \param node The node to which to add the new address and corresponding
|
||||
* interface.
|
||||
* \param netDeviceNumber The NetDevice index number with which to associate
|
||||
* the address.
|
||||
* \param address The Ipv4 Address for the interface.
|
||||
* \param network The network mask for the interface
|
||||
*
|
||||
* Add an Ipv4Address to the Ipv4 interface associated with the
|
||||
* ndNum CsmaIpv4NetDevices on the provided
|
||||
* CsmaIpv4Channel
|
||||
* ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel
|
||||
*/
|
||||
static void AddIpv4Address(Ptr<Node> n1, int ndNum,
|
||||
const Ipv4Address& addr1,
|
||||
const Ipv4Mask& netmask1);
|
||||
static uint32_t AddIpv4Address(Ptr<Node> node,
|
||||
uint32_t netDeviceNumber,
|
||||
const Ipv4Address address,
|
||||
const Ipv4Mask mask);
|
||||
|
||||
/**
|
||||
* \param nd1 Node
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/queue.h"
|
||||
#include "ns3/simulator.h"
|
||||
@@ -70,7 +68,6 @@ CsmaTraceType::Get (void) const
|
||||
return m_type;
|
||||
}
|
||||
|
||||
|
||||
CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
|
||||
: NetDevice (node, Eui48Address::Allocate ()),
|
||||
m_bps (DataRate (0xffffffff))
|
||||
@@ -81,7 +78,7 @@ CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
|
||||
}
|
||||
|
||||
CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
|
||||
CsmaEncapsulationMode encapMode)
|
||||
CsmaEncapsulationMode encapMode)
|
||||
: NetDevice(node, addr),
|
||||
m_bps (DataRate (0xffffffff))
|
||||
{
|
||||
@@ -92,8 +89,8 @@ CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
|
||||
}
|
||||
|
||||
CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
|
||||
CsmaEncapsulationMode encapMode,
|
||||
bool sendEnable, bool receiveEnable)
|
||||
CsmaEncapsulationMode encapMode,
|
||||
bool sendEnable, bool receiveEnable)
|
||||
: NetDevice(node, addr),
|
||||
m_bps (DataRate (0xffffffff))
|
||||
{
|
||||
@@ -142,7 +139,7 @@ CsmaNetDevice::Init(bool sendEnable, bool receiveEnable)
|
||||
m_queue = 0;
|
||||
|
||||
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
|
||||
EnableMulticast();
|
||||
EnableMulticast (Eui48Address ("01:00:5e:00:00:00"));
|
||||
|
||||
SetSendEnable (sendEnable);
|
||||
SetReceiveEnable (receiveEnable);
|
||||
@@ -513,10 +510,11 @@ CsmaNetDevice::Receive (const Packet& packet)
|
||||
EthernetHeader header (false);
|
||||
EthernetTrailer trailer;
|
||||
Eui48Address broadcast;
|
||||
Eui48Address multicast;
|
||||
Eui48Address destination;
|
||||
Packet p = packet;
|
||||
|
||||
NS_DEBUG ("CsmaNetDevice::Receive UID is (" << p.GetUid() << ")");
|
||||
NS_DEBUG ("CsmaNetDevice::Receive (): UID is " << p.GetUid());
|
||||
|
||||
// Only receive if send side of net device is enabled
|
||||
if (!IsReceiveEnabled())
|
||||
@@ -535,12 +533,34 @@ CsmaNetDevice::Receive (const Packet& packet)
|
||||
trailer.CheckFcs(p);
|
||||
p.RemoveHeader(header);
|
||||
|
||||
NS_DEBUG ("CsmaNetDevice::Receive (): Pkt destination is " <<
|
||||
header.GetDestination ());
|
||||
//
|
||||
// An IP host group address is mapped to an Ethernet multicast address
|
||||
// by placing the low-order 23-bits of the IP address into the low-order
|
||||
// 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex).
|
||||
//
|
||||
// We are going to receive all packets destined to any multicast address,
|
||||
// which means clearing the low-order 23 bits the header destination
|
||||
//
|
||||
Eui48Address mcDest;
|
||||
uint8_t mcBuf[6];
|
||||
|
||||
header.GetDestination ().CopyTo (mcBuf);
|
||||
mcBuf[3] &= 0x80;
|
||||
mcBuf[4] = 0;
|
||||
mcBuf[5] = 0;
|
||||
mcDest.CopyFrom (mcBuf);
|
||||
|
||||
multicast = Eui48Address::ConvertFrom (GetMulticast ());
|
||||
broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
|
||||
destination = Eui48Address::ConvertFrom (GetAddress ());
|
||||
if ((header.GetDestination() != broadcast) &&
|
||||
(header.GetDestination() != destination))
|
||||
|
||||
if ((header.GetDestination () != broadcast) &&
|
||||
(mcDest != multicast) &&
|
||||
(header.GetDestination () != destination))
|
||||
{
|
||||
// not for us.
|
||||
NS_DEBUG ("CsmaNetDevice::Receive (): Dropping pkt ");
|
||||
m_dropTrace (p);
|
||||
return;
|
||||
}
|
||||
@@ -572,6 +592,61 @@ CsmaNetDevice::Receive (const Packet& packet)
|
||||
return;
|
||||
}
|
||||
|
||||
Address
|
||||
CsmaNetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const
|
||||
{
|
||||
NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (" << multicastGroup <<
|
||||
")");
|
||||
//
|
||||
// First, get the generic multicast address.
|
||||
//
|
||||
Address hardwareDestination = GetMulticast ();
|
||||
|
||||
NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): "
|
||||
"Device multicast address: " << hardwareDestination);
|
||||
//
|
||||
// It's our address, and we know we're playing with an EUI-48 address here
|
||||
// primarily since we know that by construction, but also since the parameter
|
||||
// is an Ipv4Address.
|
||||
//
|
||||
Eui48Address etherAddr = Eui48Address::ConvertFrom (hardwareDestination);
|
||||
//
|
||||
// We now have the multicast address in an abstract 48-bit container. We
|
||||
// need to pull it out so we can play with it. When we're done, we have the
|
||||
// high order bits in etherBuffer[0], etc.
|
||||
//
|
||||
uint8_t etherBuffer[6];
|
||||
etherAddr.CopyTo (etherBuffer);
|
||||
//
|
||||
// Now we need to pull the raw bits out of the Ipv4 destination address.
|
||||
//
|
||||
uint8_t ipBuffer[4];
|
||||
multicastGroup.Serialize (ipBuffer);
|
||||
//
|
||||
// RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
|
||||
// multicast address by placing the low-order 23-bits of the IP address into
|
||||
// the low-order 23 bits of the Ethernet multicast address
|
||||
// 01-00-5E-00-00-00 (hex).
|
||||
//
|
||||
etherBuffer[3] |= ipBuffer[1] & 0x7f;
|
||||
etherBuffer[4] = ipBuffer[2];
|
||||
etherBuffer[5] = ipBuffer[3];
|
||||
//
|
||||
// Now, etherBuffer has the desired ethernet multicast address. We have to
|
||||
// suck these bits back into the Eui48Address,
|
||||
//
|
||||
etherAddr.CopyFrom (etherBuffer);
|
||||
//
|
||||
// Implicit conversion (operator Address ()) is defined for Eui48Address, so
|
||||
// use it by just returning the EUI-48 address which is automagically converted
|
||||
// to an Address.
|
||||
//
|
||||
NS_DEBUG ("CsmaNetDevice::MakeMulticastAddress (): "
|
||||
"multicast address is " << etherAddr);
|
||||
|
||||
return etherAddr;
|
||||
}
|
||||
|
||||
Ptr<Queue>
|
||||
CsmaNetDevice::GetQueue(void) const
|
||||
{
|
||||
|
||||
@@ -205,6 +205,37 @@ enum CsmaEncapsulationMode {
|
||||
*/
|
||||
void Receive (const Packet& p);
|
||||
|
||||
/**
|
||||
* @brief Make and return a MAC multicast address using the provided
|
||||
* multicast group
|
||||
*
|
||||
* RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet
|
||||
* multicast address by placing the low-order 23-bits of the IP address into
|
||||
* the low-order 23 bits of the Ethernet multicast address
|
||||
* 01-00-5E-00-00-00 (hex).
|
||||
*
|
||||
* This method performs the multicast address creation function appropriate
|
||||
* to an EUI-48-based CSMA device. This MAC address is encapsulated in an
|
||||
* abstract Address to avoid dependencies on the exact address format.
|
||||
*
|
||||
* A default imlementation of MakeMulticastAddress is provided, but this
|
||||
* method simply NS_ASSERTS. In the case of net devices that do not support
|
||||
* multicast, clients are expected to test NetDevice::IsMulticast and avoid
|
||||
* attempting to map multicast packets. Subclasses of NetDevice that do
|
||||
* support multicasting are expected to override this method and provide an
|
||||
* implementation appropriate to the particular device.
|
||||
*
|
||||
* @param multicastGroup The IP address for the multicast group destination
|
||||
* of the packet.
|
||||
* @return The MAC multicast Address used to send packets to the provided
|
||||
* multicast group.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
* @see Eui48Address
|
||||
* @see Address
|
||||
*/
|
||||
Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
|
||||
|
||||
bool IsSendEnabled (void);
|
||||
bool IsReceiveEnabled (void);
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
* Revised: George Riley <riley@ece.gatech.edu>
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/queue.h"
|
||||
#include "ns3/simulator.h"
|
||||
@@ -73,11 +71,14 @@ PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
|
||||
{
|
||||
NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")");
|
||||
|
||||
// BUGBUG FIXME
|
||||
//
|
||||
// You _must_ support broadcast to get any sort of packet from the ARP layer.
|
||||
// BUGBUG FIXME
|
||||
//
|
||||
// You _must_ support broadcast to get any sort of packet from the ARP layer.
|
||||
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
|
||||
EnableMulticast();
|
||||
//
|
||||
// We want to allow multicast packets to flow across this link
|
||||
//
|
||||
EnableMulticast (Eui48Address ("01:00:5e:00:00:00"));
|
||||
EnablePointToPoint();
|
||||
}
|
||||
|
||||
@@ -218,6 +219,8 @@ bool PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
|
||||
m_bps = m_channel->GetDataRate ();
|
||||
// GFR Comment. Below is definitely wrong. Interframe gap
|
||||
// is unrelated to channel delay.
|
||||
// -- unlesss you want to introduce a default gap which is there to avoid
|
||||
// parts of multiple packets flowing on the "wire" at the same time.
|
||||
//m_tInterframeGap = m_channel->GetDelay ();
|
||||
|
||||
/*
|
||||
|
||||
@@ -31,18 +31,26 @@
|
||||
#include "ipv4-l3-protocol.h"
|
||||
#include "arp-l3-protocol.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("ArpIpv4Interface");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
ArpIpv4Interface::ArpIpv4Interface (Ptr<Node> node, Ptr<NetDevice> device)
|
||||
: Ipv4Interface (device),
|
||||
m_node (node)
|
||||
{}
|
||||
{
|
||||
NS_DEBUG ("ArpIpv4Interface::ArpIpv4Interface ()");
|
||||
}
|
||||
|
||||
ArpIpv4Interface::~ArpIpv4Interface ()
|
||||
{}
|
||||
{
|
||||
NS_DEBUG ("ArpIpv4Interface::~ArpIpv4Interface ()");
|
||||
}
|
||||
|
||||
Ptr<TraceResolver>
|
||||
ArpIpv4Interface::GetTraceResolver (void) const
|
||||
{
|
||||
NS_DEBUG ("ArpIpv4Interface::DoCreateTraceResolver ()");
|
||||
Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
|
||||
if (GetDevice () != 0)
|
||||
{
|
||||
@@ -55,32 +63,52 @@ ArpIpv4Interface::GetTraceResolver (void) const
|
||||
void
|
||||
ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
|
||||
{
|
||||
NS_DEBUG ("ArpIpv4Interface::SendTo (" << &p << ", " << dest << ")");
|
||||
|
||||
NS_ASSERT (GetDevice () != 0);
|
||||
if (GetDevice ()->NeedsArp ())
|
||||
{
|
||||
Ptr<ArpL3Protocol> arp = m_node->QueryInterface<ArpL3Protocol> (ArpL3Protocol::iid);
|
||||
NS_DEBUG ("ArpIpv4Interface::SendTo (): Needs ARP");
|
||||
Ptr<ArpL3Protocol> arp =
|
||||
m_node->QueryInterface<ArpL3Protocol> (ArpL3Protocol::iid);
|
||||
Address hardwareDestination;
|
||||
bool found;
|
||||
|
||||
if (dest.IsBroadcast () ||
|
||||
dest.IsSubnetDirectedBroadcast (GetNetworkMask ()) )
|
||||
{
|
||||
NS_DEBUG ("ArpIpv4Interface::SendTo (): IsBroadcast");
|
||||
hardwareDestination = GetDevice ()->GetBroadcast ();
|
||||
found = true;
|
||||
}
|
||||
else if (dest.IsMulticast ())
|
||||
{
|
||||
NS_DEBUG ("ArpIpv4Interface::SendTo (): IsMulticast");
|
||||
NS_ASSERT_MSG(GetDevice ()->IsMulticast (),
|
||||
"ArpIpv4Interface::SendTo (): Sending multicast packet over "
|
||||
"non-multicast device");
|
||||
|
||||
hardwareDestination = GetDevice ()->MakeMulticastAddress(dest);
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_DEBUG ("ArpIpv4Interface::SendTo (): ARP Lookup");
|
||||
found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
GetDevice ()->Send (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER);
|
||||
NS_DEBUG ("ArpIpv4Interface::SendTo (): Address Resolved. Send.");
|
||||
GetDevice ()->Send (p, hardwareDestination,
|
||||
Ipv4L3Protocol::PROT_NUMBER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDevice ()->Send (p, GetDevice ()->GetBroadcast (), Ipv4L3Protocol::PROT_NUMBER);
|
||||
NS_DEBUG ("ArpIpv4Interface::SendTo (): Doesn't need ARP");
|
||||
GetDevice ()->Send (p, GetDevice ()->GetBroadcast (),
|
||||
Ipv4L3Protocol::PROT_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "ipv4-interface.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/eui48-address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
@@ -95,22 +95,90 @@ Ipv4Impl::RemoveRoute (uint32_t i)
|
||||
{
|
||||
return m_ipv4->RemoveRoute (i);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces)
|
||||
{
|
||||
m_ipv4->AddMulticastRoute (origin, group, inputInterface, outputInterfaces);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::SetDefaultMulticastRoute (uint32_t outputInterface)
|
||||
{
|
||||
m_ipv4->SetDefaultMulticastRoute (outputInterface);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4Impl::GetNMulticastRoutes (void) const
|
||||
{
|
||||
return m_ipv4->GetNMulticastRoutes ();
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute
|
||||
Ipv4Impl::GetMulticastRoute (uint32_t i) const
|
||||
{
|
||||
return *m_ipv4->GetMulticastRoute (i);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface)
|
||||
{
|
||||
m_ipv4->RemoveMulticastRoute (origin, group, inputInterface);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::RemoveMulticastRoute (uint32_t i)
|
||||
{
|
||||
return m_ipv4->RemoveMulticastRoute (i);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4Impl::AddInterface (Ptr<NetDevice> device)
|
||||
{
|
||||
return m_ipv4->AddInterface (device);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4Impl::GetNInterfaces (void)
|
||||
{
|
||||
return m_ipv4->GetNInterfaces ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr) const
|
||||
{
|
||||
return m_ipv4->FindInterfaceForAddr (addr);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4Impl::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
|
||||
{
|
||||
return m_ipv4->FindInterfaceForAddr (addr, mask);
|
||||
}
|
||||
|
||||
Ptr<NetDevice>
|
||||
Ipv4Impl::GetNetDevice (uint32_t i)
|
||||
{
|
||||
return m_ipv4->GetInterface (i)-> GetDevice ();
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
|
||||
{
|
||||
m_ipv4->JoinMulticastGroup(origin, group);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
|
||||
{
|
||||
m_ipv4->LeaveMulticastGroup(origin, group);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::SetAddress (uint32_t i, Ipv4Address address)
|
||||
{
|
||||
@@ -126,11 +194,39 @@ Ipv4Impl::GetNetworkMask (uint32_t i) const
|
||||
{
|
||||
return m_ipv4->GetNetworkMask (i);
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4Impl::GetAddress (uint32_t i) const
|
||||
{
|
||||
return m_ipv4->GetAddress (i);
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const
|
||||
{
|
||||
return m_ipv4->GetIfIndexForDestination (dest, ifIndex);
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4Impl::GetSourceAddress (Ipv4Address destination) const
|
||||
{
|
||||
uint32_t ifIndex = 0xffffffff;
|
||||
|
||||
bool result = m_ipv4->GetIfIndexForDestination (destination, ifIndex);
|
||||
|
||||
if (result)
|
||||
{
|
||||
return m_ipv4->GetAddress (ifIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// If we can't find any address, just leave it 0.0.0.0
|
||||
//
|
||||
return Ipv4Address::GetAny ();
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Ipv4Impl::GetMtu (uint32_t i) const
|
||||
{
|
||||
|
||||
@@ -55,14 +55,43 @@ public:
|
||||
virtual uint32_t GetNRoutes (void);
|
||||
virtual Ipv4Route GetRoute (uint32_t i);
|
||||
virtual void RemoveRoute (uint32_t i);
|
||||
|
||||
|
||||
virtual void AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces);
|
||||
|
||||
virtual void SetDefaultMulticastRoute (uint32_t outputInterface);
|
||||
|
||||
virtual uint32_t GetNMulticastRoutes (void) const;
|
||||
virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const;
|
||||
|
||||
virtual void RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface);
|
||||
virtual void RemoveMulticastRoute (uint32_t i);
|
||||
|
||||
virtual uint32_t AddInterface (Ptr<NetDevice> device);
|
||||
virtual uint32_t GetNInterfaces (void);
|
||||
|
||||
virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
|
||||
virtual uint32_t FindInterfaceForAddr (Ipv4Address addr,
|
||||
Ipv4Mask mask) const;
|
||||
|
||||
virtual Ptr<NetDevice> GetNetDevice(uint32_t i);
|
||||
|
||||
virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
|
||||
virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
|
||||
|
||||
virtual void SetAddress (uint32_t i, Ipv4Address address);
|
||||
virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
|
||||
virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
|
||||
virtual Ipv4Address GetAddress (uint32_t i) const;
|
||||
virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const;
|
||||
virtual bool GetIfIndexForDestination (Ipv4Address dest,
|
||||
uint32_t &ifIndex) const;
|
||||
|
||||
virtual uint16_t GetMtu (uint32_t i) const;
|
||||
virtual bool IsUp (uint32_t i) const;
|
||||
virtual void SetUp (uint32_t i);
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/trace-resolver.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("Ipv4Interface");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -35,10 +38,14 @@ namespace ns3 {
|
||||
Ipv4Interface::Ipv4Interface (Ptr<NetDevice> nd)
|
||||
: m_netdevice (nd),
|
||||
m_ifup(false)
|
||||
{}
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::Ipv4Interface (" << &nd << ")");
|
||||
}
|
||||
|
||||
Ipv4Interface::~Ipv4Interface ()
|
||||
{}
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::~Ipv4Interface ()");
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::DoDispose (void)
|
||||
@@ -50,42 +57,53 @@ Ipv4Interface::DoDispose (void)
|
||||
Ptr<NetDevice>
|
||||
Ipv4Interface::GetDevice (void) const
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::GetDevice ()");
|
||||
return m_netdevice;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetAddress (Ipv4Address a)
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::SetAddress (" << a << ")");
|
||||
m_address = a;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetNetworkMask (Ipv4Mask mask)
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::SetMask (" << mask << ")");
|
||||
m_netmask = mask;
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4Interface::GetBroadcast (void) const
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::GetBroadcast ()");
|
||||
|
||||
uint32_t mask = m_netmask.GetHostOrder ();
|
||||
uint32_t address = m_address.GetHostOrder ();
|
||||
Ipv4Address broadcast = Ipv4Address (address | (~mask));
|
||||
return broadcast;
|
||||
}
|
||||
|
||||
Ipv4Mask
|
||||
Ipv4Interface::GetNetworkMask (void) const
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::GetNetworkMask ()");
|
||||
return m_netmask;
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4Interface::GetAddress (void) const
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::Address ()");
|
||||
return m_address;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Ipv4Interface::GetMtu (void) const
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::GetMtu ()");
|
||||
if (m_netdevice == 0)
|
||||
{
|
||||
uint32_t mtu = (1<<16) - 1;
|
||||
@@ -94,32 +112,36 @@ Ipv4Interface::GetMtu (void) const
|
||||
return m_netdevice->GetMtu ();
|
||||
}
|
||||
|
||||
/**
|
||||
* These are IP interface states and may be distinct from
|
||||
* NetDevice states, such as found in real implementations
|
||||
* (where the device may be down but IP interface state is still up).
|
||||
*/
|
||||
/**
|
||||
* These are IP interface states and may be distinct from
|
||||
* NetDevice states, such as found in real implementations
|
||||
* (where the device may be down but IP interface state is still up).
|
||||
*/
|
||||
bool
|
||||
Ipv4Interface::IsUp (void) const
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::IsUp ()");
|
||||
return m_ifup;
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4Interface::IsDown (void) const
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::IsDown ()");
|
||||
return !m_ifup;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetUp (void)
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::SetUp ()");
|
||||
m_ifup = true;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetDown (void)
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::SetDown ()");
|
||||
m_ifup = false;
|
||||
}
|
||||
|
||||
@@ -127,7 +149,10 @@ Ipv4Interface::SetDown (void)
|
||||
void
|
||||
Ipv4Interface::Send(Packet p, Ipv4Address dest)
|
||||
{
|
||||
NS_DEBUG ("Ipv4Interface::Send ()");
|
||||
|
||||
if (IsUp()) {
|
||||
NS_DEBUG ("Ipv4Interface::Send (): SendTo ()");
|
||||
SendTo(p, dest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,17 +129,24 @@ Ipv4L3Protocol::Ipv4L3Protocol(Ptr<Node> node)
|
||||
m_identification (0),
|
||||
m_node (node)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::Ipv4L3Protocol ()");
|
||||
|
||||
SetInterfaceId (Ipv4L3Protocol::iid);
|
||||
m_staticRouting = Create<Ipv4StaticRouting> ();
|
||||
AddRoutingProtocol (m_staticRouting, 0);
|
||||
SetupLoopback ();
|
||||
}
|
||||
|
||||
Ipv4L3Protocol::~Ipv4L3Protocol ()
|
||||
{}
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::~Ipv4L3Protocol ()");
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::DoDispose (void)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::DoDispose ()");
|
||||
|
||||
m_interfaces.clear ();
|
||||
m_node = 0;
|
||||
m_staticRouting->Dispose ();
|
||||
@@ -150,6 +157,8 @@ Ipv4L3Protocol::DoDispose (void)
|
||||
void
|
||||
Ipv4L3Protocol::SetupLoopback (void)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetupLoopback ()");
|
||||
|
||||
Ptr<Ipv4LoopbackInterface> interface = Create<Ipv4LoopbackInterface> (m_node);
|
||||
interface->SetAddress (Ipv4Address::GetLoopback ());
|
||||
interface->SetNetworkMask (Ipv4Mask::GetLoopback ());
|
||||
@@ -161,6 +170,8 @@ Ipv4L3Protocol::SetupLoopback (void)
|
||||
Ptr<TraceResolver>
|
||||
Ipv4L3Protocol::GetTraceResolver (void) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetTraceResolver ()");
|
||||
|
||||
Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
|
||||
resolver->AddSource ("tx",
|
||||
TraceDoc ("send ipv4 packet to outgoing interface",
|
||||
@@ -185,6 +196,7 @@ Ipv4L3Protocol::GetTraceResolver (void) const
|
||||
void
|
||||
Ipv4L3Protocol::SetDefaultTtl (uint8_t ttl)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetDefaultTtl ()");
|
||||
m_defaultTtl = ttl;
|
||||
}
|
||||
|
||||
@@ -194,20 +206,28 @@ Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddHostRouteTo (" << dest << ", " << nextHop <<
|
||||
", " << interface << ")");
|
||||
m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
|
||||
uint32_t interface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddHostRouteTo (" << dest << ", " <<
|
||||
interface << ")");
|
||||
m_staticRouting->AddHostRouteTo (dest, interface);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddNetworkRouteTo (" << network << ", " <<
|
||||
networkMask << ", " << nextHop << ", " << interface << ")");
|
||||
m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
|
||||
}
|
||||
void
|
||||
@@ -215,28 +235,81 @@ Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
uint32_t interface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddNetworkRouteTo (" << network << ", " <<
|
||||
networkMask << ", " << interface << ")");
|
||||
m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
|
||||
}
|
||||
void
|
||||
Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetDefaultRoute (" << nextHop << ", " <<
|
||||
interface << ")");
|
||||
m_staticRouting->SetDefaultRoute (nextHop, interface);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::Lookup (
|
||||
Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader <<
|
||||
", " << &packet << &routeReply << ")");
|
||||
|
||||
Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
|
||||
Ipv4L3Protocol::Lookup (
|
||||
uint32_t ifIndex,
|
||||
Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
Ipv4RoutingProtocol::RouteReplyCallback routeReply)
|
||||
{
|
||||
for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
|
||||
rprotoIter != m_routingProtocols.end (); rprotoIter++)
|
||||
NS_DEBUG("Ipv4L3Protocol::Lookup (" << ifIndex << ", " << &ipHeader <<
|
||||
", " << &packet << &routeReply << ")");
|
||||
|
||||
for (Ipv4RoutingProtocolList::const_iterator rprotoIter =
|
||||
m_routingProtocols.begin ();
|
||||
rprotoIter != m_routingProtocols.end ();
|
||||
rprotoIter++)
|
||||
{
|
||||
if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply))
|
||||
NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting route");
|
||||
if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet,
|
||||
routeReply))
|
||||
return;
|
||||
}
|
||||
// No route found
|
||||
|
||||
if (ipHeader.GetDestination ().IsMulticast () &&
|
||||
ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY)
|
||||
{
|
||||
NS_DEBUG ("Ipv4L3Protocol::Lookup (): "
|
||||
"Multicast destination with local source");
|
||||
//
|
||||
// We have a multicast packet originating from the current node and were not
|
||||
// able to send it using the usual RequestRoute process. Since the usual
|
||||
// process includes trying to use a default multicast route, this means that
|
||||
// there was no specific route out of the node found, and there was no default
|
||||
// multicast route set.
|
||||
//
|
||||
// The fallback position is to look for a default unicast route and use that
|
||||
// to get the packet off the node if we have one.
|
||||
//
|
||||
Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
|
||||
|
||||
if (route)
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::Lookup (): "
|
||||
"Local source. Using unicast default route for multicast packet");
|
||||
|
||||
routeReply (true, *route, packet, ipHeader);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//
|
||||
// No route found
|
||||
//
|
||||
routeReply (false, Ipv4Route (), packet, ipHeader);
|
||||
}
|
||||
|
||||
@@ -244,6 +317,8 @@ void
|
||||
Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
int priority)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddRoutingProtocol (" << &routingProtocol <<
|
||||
", " << priority << ")");
|
||||
m_routingProtocols.push_back
|
||||
(std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
|
||||
m_routingProtocols.sort ();
|
||||
@@ -252,39 +327,99 @@ Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
|
||||
uint32_t
|
||||
Ipv4L3Protocol::GetNRoutes (void)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetNRoutes ()");
|
||||
return m_staticRouting->GetNRoutes ();
|
||||
}
|
||||
|
||||
Ipv4Route *
|
||||
Ipv4L3Protocol::GetRoute (uint32_t index)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetRoute ()");
|
||||
return m_staticRouting->GetRoute (index);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::RemoveRoute (uint32_t index)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::RemoveRoute (" << index << ")");
|
||||
m_staticRouting->RemoveRoute (index);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddMulticastRoute (" << origin << ", " <<
|
||||
group << ", " << inputInterface << ", " << &outputInterfaces << ")");
|
||||
|
||||
m_staticRouting->AddMulticastRoute (origin, group, inputInterface,
|
||||
outputInterfaces);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::SetDefaultMulticastRoute (uint32_t outputInterface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetDefaultMulticastRoute (" << outputInterface <<
|
||||
")");
|
||||
|
||||
m_staticRouting->SetDefaultMulticastRoute (outputInterface);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3Protocol::GetNMulticastRoutes (void) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetNMulticastRoutes ()");
|
||||
return m_staticRouting->GetNMulticastRoutes ();
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute *
|
||||
Ipv4L3Protocol::GetMulticastRoute (uint32_t index) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetMulticastRoute (" << index << ")");
|
||||
return m_staticRouting->GetMulticastRoute (index);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::RemoveMulticastRoute (" << origin << ", " <<
|
||||
group << ", " << inputInterface << ")");
|
||||
m_staticRouting->RemoveMulticastRoute (origin, group, inputInterface);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::RemoveMulticastRoute (uint32_t index)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::RemoveMulticastRoute (" << index << ")");
|
||||
m_staticRouting->RemoveMulticastRoute (index);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3Protocol::AddInterface (Ptr<NetDevice> device)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddInterface (" << &device << ")");
|
||||
Ptr<Ipv4Interface> interface = Create<ArpIpv4Interface> (m_node, device);
|
||||
return AddIpv4Interface (interface);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3Protocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::AddIpv4Interface (" << interface << ")");
|
||||
uint32_t index = m_nInterfaces;
|
||||
m_interfaces.push_back (interface);
|
||||
m_nInterfaces++;
|
||||
return index;
|
||||
}
|
||||
|
||||
Ptr<Ipv4Interface>
|
||||
Ipv4L3Protocol::GetInterface (uint32_t index) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetInterface (" << index << ")");
|
||||
uint32_t tmp = 0;
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
|
||||
{
|
||||
@@ -296,15 +431,61 @@ Ipv4L3Protocol::GetInterface (uint32_t index) const
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3Protocol::GetNInterfaces (void) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetNInterface ()");
|
||||
return m_nInterfaces;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::FindInterfaceForAddr (" << addr << ")");
|
||||
|
||||
uint32_t ifIndex = 0;
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
||||
i != m_interfaces.end ();
|
||||
i++, ifIndex++)
|
||||
{
|
||||
if ((*i)->GetAddress () == addr)
|
||||
{
|
||||
return ifIndex;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
|
||||
"Interface not found for IP address");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3Protocol::FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::FindInterfaceForAddr (" << addr << ", " <<
|
||||
mask << ")");
|
||||
|
||||
uint32_t ifIndex = 0;
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
||||
i != m_interfaces.end ();
|
||||
i++, ifIndex++)
|
||||
{
|
||||
if ((*i)->GetAddress ().CombineMask (mask) == addr.CombineMask (mask))
|
||||
{
|
||||
return ifIndex;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERT_MSG(false, "Ipv4L3Protocol::FindInterfaceForAddr (): "
|
||||
"Interface not found for masked IP address");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ptr<Ipv4Interface>
|
||||
Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::FindInterfaceForDevice (" << &device << ")");
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
|
||||
{
|
||||
if ((*i)->GetDevice () == device)
|
||||
@@ -318,8 +499,15 @@ Ipv4L3Protocol::FindInterfaceForDevice (Ptr<const NetDevice> device)
|
||||
void
|
||||
Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protocol, const Address &from)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::Receive (" << &device << ", " << &p << ", " <<
|
||||
protocol << ", " << from << ")");
|
||||
|
||||
NS_DEBUG("Ipv4L3Protocol::Receive (): Packet from " << from);
|
||||
|
||||
uint32_t index = 0;
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
||||
i != m_interfaces.end ();
|
||||
i++)
|
||||
{
|
||||
if ((*i)->GetDevice () == device)
|
||||
{
|
||||
@@ -337,7 +525,7 @@ Ipv4L3Protocol::Receive( Ptr<NetDevice> device, const Packet& p, uint16_t protoc
|
||||
return;
|
||||
}
|
||||
|
||||
if (Forwarding (packet, ipHeader, device))
|
||||
if (Forwarding (index, packet, ipHeader, device))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -352,6 +540,9 @@ Ipv4L3Protocol::Send (Packet const &packet,
|
||||
Ipv4Address destination,
|
||||
uint8_t protocol)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::Send (" << &packet << ", " << source << ", " <<
|
||||
", " << destination << ", " << protocol << ")");
|
||||
|
||||
Ipv4Header ipHeader;
|
||||
|
||||
ipHeader.SetSource (source);
|
||||
@@ -400,36 +591,54 @@ Ipv4L3Protocol::SendRealOut (bool found,
|
||||
Packet packet,
|
||||
Ipv4Header const &ipHeader)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SendRealOut (" << found << ", " << &route <<
|
||||
", " << &packet << &ipHeader << ")");
|
||||
|
||||
if (!found)
|
||||
{
|
||||
NS_DEBUG ("no route to host. drop.");
|
||||
NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): No route to host. Drop.");
|
||||
m_dropTrace (packet);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send via interface " <<
|
||||
route.GetInterface ());
|
||||
|
||||
packet.AddHeader (ipHeader);
|
||||
Ptr<Ipv4Interface> outInterface = GetInterface (route.GetInterface ());
|
||||
NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
|
||||
m_txTrace (packet, route.GetInterface ());
|
||||
if (route.IsGateway ())
|
||||
{
|
||||
NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send to gateway " <<
|
||||
route.GetGateway ());
|
||||
outInterface->Send (packet, route.GetGateway ());
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_DEBUG ("Ipv4L3Protocol::SendRealOut (): Send to destination " <<
|
||||
ipHeader.GetDestination ());
|
||||
outInterface->Send (packet, ipHeader.GetDestination ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device)
|
||||
Ipv4L3Protocol::Forwarding (
|
||||
uint32_t ifIndex,
|
||||
Packet const &packet,
|
||||
Ipv4Header &ipHeader,
|
||||
Ptr<NetDevice> device)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (" << ifIndex << ", " << &packet <<
|
||||
", " << &ipHeader << ", " << device << ")");
|
||||
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
||||
i != m_interfaces.end (); i++)
|
||||
{
|
||||
if ((*i)->GetAddress ().IsEqual (ipHeader.GetDestination ()))
|
||||
{
|
||||
NS_DEBUG ("for me 1");
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): "
|
||||
"For me (destination match)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -442,7 +651,8 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetD
|
||||
{
|
||||
if (ipHeader.GetDestination ().IsEqual (interface->GetBroadcast ()))
|
||||
{
|
||||
NS_DEBUG ("for me 2");
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): "
|
||||
"For me (interface broadcast address)");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -451,78 +661,213 @@ Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetD
|
||||
|
||||
if (ipHeader.GetDestination ().IsBroadcast ())
|
||||
{
|
||||
NS_DEBUG ("for me 3");
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): "
|
||||
"For me (Ipv4Addr broadcast address)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetAny ()))
|
||||
{
|
||||
NS_DEBUG ("for me 4");
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): "
|
||||
"For me (Ipv4Addr any address)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ipHeader.GetTtl () == 1)
|
||||
{
|
||||
// Should send ttl expired here
|
||||
// XXX
|
||||
NS_DEBUG ("not for me -- ttl expired. drop.");
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): "
|
||||
"Not for me (TTL expired). Drop");
|
||||
m_dropTrace (packet);
|
||||
return true;
|
||||
}
|
||||
ipHeader.SetTtl (ipHeader.GetTtl () - 1);
|
||||
|
||||
NS_DEBUG ("not for me -- forwarding.");
|
||||
Lookup (ipHeader, packet,
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): Forwarding packet.");
|
||||
Lookup (ifIndex, ipHeader, packet,
|
||||
MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
|
||||
//
|
||||
// If this is a to a multicast address and this node is a member of the
|
||||
// indicated group we need to return false so the multicast is forwarded up.
|
||||
// Note that we may have just forwarded this packet too.
|
||||
//
|
||||
for (Ipv4MulticastGroupList::const_iterator i = m_multicastGroups.begin ();
|
||||
i != m_multicastGroups.end (); i++)
|
||||
{
|
||||
if ((*i).first.IsEqual (ipHeader.GetSource ()) &&
|
||||
(*i).second.IsEqual (ipHeader.GetDestination ()))
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): "
|
||||
"For me (Joined multicast group)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NS_DEBUG("Ipv4L3Protocol::Forwarding (): Not for me.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::ForwardUp (Packet p, Ipv4Header const&ip)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::ForwardUp (" << &p << ", " << &ip << ")");
|
||||
Ptr<Ipv4L4Demux> demux = m_node->QueryInterface<Ipv4L4Demux> (Ipv4L4Demux::iid);
|
||||
Ptr<Ipv4L4Protocol> protocol = demux->GetProtocol (ip.GetProtocol ());
|
||||
protocol->Receive (p, ip.GetSource (), ip.GetDestination ());
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::JoinMulticastGroup (Ipv4Address origin, Ipv4Address group)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::JoinMulticastGroup (" << origin << ", " <<
|
||||
group << ")");
|
||||
m_multicastGroups.push_back(
|
||||
std::pair<Ipv4Address, Ipv4Address> (origin, group));
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::LeaveMulticastGroup (" << origin << ", " <<
|
||||
group << ")");
|
||||
|
||||
for (Ipv4MulticastGroupList::iterator i = m_multicastGroups.begin ();
|
||||
i != m_multicastGroups.end ();
|
||||
i++)
|
||||
{
|
||||
if ((*i).first.IsEqual(origin) && (*i).second.IsEqual(group))
|
||||
{
|
||||
m_multicastGroups.erase (i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::SetAddress (uint32_t i, Ipv4Address address)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetAddress (" << i << ", " << address << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
interface->SetAddress (address);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::SetNetworkMask (uint32_t i, Ipv4Mask mask)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetNetworkMask (" << i << ", " << mask << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
interface->SetNetworkMask (mask);
|
||||
}
|
||||
|
||||
Ipv4Mask
|
||||
Ipv4L3Protocol::GetNetworkMask (uint32_t i) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetNetworkMask (" << i << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
return interface->GetNetworkMask ();
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4L3Protocol::GetAddress (uint32_t i) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetAddress (" << i << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
return interface->GetAddress ();
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4L3Protocol::GetIfIndexForDestination (
|
||||
Ipv4Address destination, uint32_t& ifIndex) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (" << destination <<
|
||||
", " << &ifIndex << ")");
|
||||
//
|
||||
// The first thing we do in trying to determine a source address is to
|
||||
// consult the routing protocols. These will also check for a default route
|
||||
// if one has been set.
|
||||
//
|
||||
for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin ();
|
||||
i != m_routingProtocols.end ();
|
||||
i++)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting Source Address");
|
||||
uint32_t ifIndexTmp;
|
||||
|
||||
if ((*i).second->RequestIfIndex (destination, ifIndexTmp))
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): "
|
||||
"Found ifIndex " << ifIndexTmp);
|
||||
ifIndex = ifIndexTmp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//
|
||||
// If there's no routing table entry telling us what *single* interface will
|
||||
// be used to send a packet to this destination, we'll have to just pick one.
|
||||
// If there's only one interface on this node, a good answer isn't very hard
|
||||
// to come up with. Before jumping to any conclusions, remember that the
|
||||
// zeroth interface is the loopback interface, so what we actually want is
|
||||
// a situation where there are exactly two interfaces on the node, in which
|
||||
// case interface one is the "single" interface connected to the outside world.
|
||||
//
|
||||
if (GetNInterfaces () == 2)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): "
|
||||
"One Interface. Using interface 1.");
|
||||
ifIndex = 1;
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// If we fall through to here, we have a node with multiple interfaces and
|
||||
// no routes to guide us in determining what interface to choose. Either
|
||||
// no default route was found (for unicast or multicast), or in the case of a
|
||||
// multicast, the default route contained multiple outbound interfaces.
|
||||
//
|
||||
// The fallback position is to just get the unicast default route and use
|
||||
// the outgoing interface specified there. We don't want to leave the source
|
||||
// address unset, so we just assert here.
|
||||
//
|
||||
// N.B. that in the case of a multicast with a route containing multiple
|
||||
// outgoing interfaces, the source address of packets from that node will be
|
||||
// set to the IP address of the interface set in the default unicast route.
|
||||
// Also, in the case of a broadcast, the same will be true.
|
||||
//
|
||||
NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): "
|
||||
"Using default unicast route");
|
||||
Ipv4Route *route = m_staticRouting->GetDefaultRoute ();
|
||||
|
||||
NS_ASSERT_MSG(route,
|
||||
"Ipv4L3Protocol::GetIfIndexForDestination (): "
|
||||
"Unable to determine outbound interface. No default route set");
|
||||
|
||||
ifIndex = route->GetInterface ();
|
||||
|
||||
NS_DEBUG("Ipv4L3Protocol::GetIfIndexForDestination (): "
|
||||
"Default route specifies interface " << ifIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Ipv4L3Protocol::GetMtu (uint32_t i) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::GetMtu (" << i << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
return interface->GetMtu ();
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4L3Protocol::IsUp (uint32_t i) const
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::IsUp (" << i << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
return interface->IsUp ();
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::SetUp (uint32_t i)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetUp (" << i << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
interface->SetUp ();
|
||||
|
||||
@@ -536,9 +881,11 @@ Ipv4L3Protocol::SetUp (uint32_t i)
|
||||
interface->GetNetworkMask (), i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
|
||||
{
|
||||
NS_DEBUG("Ipv4L3Protocol::SetDown (" << ifaceIndex << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
|
||||
interface->SetDown ();
|
||||
|
||||
|
||||
@@ -169,15 +169,37 @@ public:
|
||||
Ipv4Route *GetRoute (uint32_t i);
|
||||
void RemoveRoute (uint32_t i);
|
||||
|
||||
void AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces);
|
||||
|
||||
void SetDefaultMulticastRoute (uint32_t onputInterface);
|
||||
|
||||
uint32_t GetNMulticastRoutes (void) const;
|
||||
Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
|
||||
|
||||
void RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface);
|
||||
void RemoveMulticastRoute (uint32_t i);
|
||||
|
||||
uint32_t AddInterface (Ptr<NetDevice> device);
|
||||
Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
|
||||
uint32_t GetNInterfaces (void) const;
|
||||
|
||||
uint32_t FindInterfaceForAddr (Ipv4Address addr) const;
|
||||
uint32_t FindInterfaceForAddr (Ipv4Address addr, Ipv4Mask mask) const;
|
||||
|
||||
void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group);
|
||||
void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group);
|
||||
|
||||
void SetAddress (uint32_t i, Ipv4Address address);
|
||||
void SetNetworkMask (uint32_t i, Ipv4Mask mask);
|
||||
Ipv4Mask GetNetworkMask (uint32_t t) const;
|
||||
Ipv4Address GetAddress (uint32_t i) const;
|
||||
bool GetIfIndexForDestination (Ipv4Address destination,
|
||||
uint32_t& ifIndex) const;
|
||||
uint16_t GetMtu (uint32_t i) const;
|
||||
bool IsUp (uint32_t i) const;
|
||||
void SetUp (uint32_t i);
|
||||
@@ -192,17 +214,26 @@ protected:
|
||||
virtual Ptr<TraceResolver> GetTraceResolver (void) const;
|
||||
|
||||
private:
|
||||
void Lookup (uint32_t ifIndex,
|
||||
Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
Ipv4RoutingProtocol::RouteReplyCallback routeReply);
|
||||
|
||||
void SendRealOut (bool found,
|
||||
Ipv4Route const &route,
|
||||
Packet packet,
|
||||
Ipv4Header const &ipHeader);
|
||||
bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
|
||||
bool Forwarding (uint32_t ifIndex,
|
||||
Packet const &packet,
|
||||
Ipv4Header &ipHeader,
|
||||
Ptr<NetDevice> device);
|
||||
void ForwardUp (Packet p, Ipv4Header const&ip);
|
||||
uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
|
||||
void SetupLoopback (void);
|
||||
|
||||
typedef std::list<Ptr<Ipv4Interface> > Ipv4InterfaceList;
|
||||
typedef std::list<std::pair<Ipv4Address, Ipv4Address> >
|
||||
Ipv4MulticastGroupList;
|
||||
typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
|
||||
|
||||
Ipv4InterfaceList m_interfaces;
|
||||
@@ -217,6 +248,7 @@ private:
|
||||
Ipv4RoutingProtocolList m_routingProtocols;
|
||||
|
||||
Ptr<Ipv4StaticRouting> m_staticRouting;
|
||||
Ipv4MulticastGroupList m_multicastGroups;
|
||||
};
|
||||
|
||||
} // Namespace ns3
|
||||
|
||||
@@ -19,25 +19,41 @@
|
||||
* Authors:
|
||||
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
|
||||
*/
|
||||
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/eui48-address.h"
|
||||
#include "ipv4-loopback-interface.h"
|
||||
#include "ipv4-l3-protocol.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("Ipv4LoopbackInterface");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Ipv4LoopbackInterface::Ipv4LoopbackInterface (Ptr<Node> node)
|
||||
: Ipv4Interface (0),
|
||||
m_node (node)
|
||||
{}
|
||||
{
|
||||
NS_DEBUG("Ipv4LoopbackInterface::Ipv4LoopbackInterface ()");
|
||||
}
|
||||
|
||||
Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()
|
||||
{}
|
||||
{
|
||||
NS_DEBUG("Ipv4LoopbackInterface::~Ipv4LoopbackInterface ()");
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
|
||||
{
|
||||
Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
|
||||
ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, Eui48Address ("ff:ff:ff:ff:ff:ff"));
|
||||
NS_DEBUG("Ipv4LoopbackInterface::SendTo (" << &packet << ", " <<
|
||||
dest << ")");
|
||||
|
||||
Ptr<Ipv4L3Protocol> ipv4 =
|
||||
m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
|
||||
|
||||
ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER,
|
||||
Eui48Address ("ff:ff:ff:ff:ff:ff"));
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
@@ -19,22 +19,30 @@
|
||||
// Author: George F. Riley<riley@ece.gatech.edu>
|
||||
// Gustavo Carneiro <gjc@inescporto.pt>
|
||||
|
||||
#include "ns3/debug.h"
|
||||
#include "ipv4-static-routing.h"
|
||||
#include "ns3/packet.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("Ipv4StaticRouting");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
Ipv4StaticRouting::Ipv4StaticRouting ()
|
||||
: m_defaultRoute (0), m_defaultMulticastRoute (0)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
{
|
||||
|
||||
Ipv4Route *route = new Ipv4Route ();
|
||||
*route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
|
||||
m_hostRoutes.push_back (route);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
|
||||
uint32_t interface)
|
||||
@@ -43,6 +51,7 @@ Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
|
||||
*route = Ipv4Route::CreateHostRouteTo (dest, interface);
|
||||
m_hostRoutes.push_back (route);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
@@ -56,6 +65,7 @@ Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
|
||||
interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
@@ -67,6 +77,7 @@ Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
|
||||
interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop,
|
||||
uint32_t interface)
|
||||
@@ -77,6 +88,168 @@ Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop,
|
||||
m_defaultRoute = route;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::AddMulticastRoute(Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces)
|
||||
{
|
||||
Ipv4MulticastRoute *route = new Ipv4MulticastRoute ();
|
||||
*route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group,
|
||||
inputInterface, outputInterfaces);
|
||||
m_multicastRoutes.push_back (route);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::SetDefaultMulticastRoute(uint32_t outputInterface)
|
||||
{
|
||||
Ipv4Address origin = Ipv4Address::GetAny ();
|
||||
Ipv4Address group = Ipv4Address::GetAny ();
|
||||
uint32_t inputInterface = Ipv4RoutingProtocol::IF_INDEX_ANY;
|
||||
|
||||
std::vector<uint32_t> outputInterfaces (1);
|
||||
outputInterfaces[0] = outputInterface;
|
||||
|
||||
Ipv4MulticastRoute *route = new Ipv4MulticastRoute ();
|
||||
*route = Ipv4MulticastRoute::CreateMulticastRoute (origin, group,
|
||||
inputInterface, outputInterfaces);
|
||||
|
||||
delete m_defaultMulticastRoute;
|
||||
m_defaultMulticastRoute = route;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4StaticRouting::GetNMulticastRoutes (void) const
|
||||
{
|
||||
return m_multicastRoutes.size () + m_defaultMulticastRoute ? 1 : 0;
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute *
|
||||
Ipv4StaticRouting::GetMulticastRoute (uint32_t index) const
|
||||
{
|
||||
NS_ASSERT_MSG(index < m_multicastRoutes.size (),
|
||||
"Ipv4StaticRouting::GetMulticastRoute (): Index out of range");
|
||||
//
|
||||
// From an external point of view the default route appears to be in slot 0
|
||||
// of the routing table. The implementation, however, puts it in a separate
|
||||
// place. So, if a client asks for index 0 and we have a default multicast
|
||||
// route, we have to return it from that different place
|
||||
// (m_defaultMulticastRoute).
|
||||
//
|
||||
if (index == 0 && m_defaultMulticastRoute != 0)
|
||||
{
|
||||
return m_defaultMulticastRoute;
|
||||
}
|
||||
//
|
||||
// If there is a default multicast route present, a client will just assume
|
||||
// that it is in slot zero and there is one "extra" zeroth route in the table.
|
||||
// To return the correct indexed entry in our list, we have to decrement the
|
||||
// index to take into account the default route not being in the actual list.
|
||||
// Since we fell through to here, we've taken care of the case where the
|
||||
// index was zero.
|
||||
//
|
||||
if (m_defaultMulticastRoute != 0)
|
||||
{
|
||||
NS_ASSERT(index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
if (index < m_multicastRoutes.size ())
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (MulticastRoutesCI i = m_multicastRoutes.begin ();
|
||||
i != m_multicastRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute *
|
||||
Ipv4StaticRouting::GetDefaultMulticastRoute () const
|
||||
{
|
||||
if (m_defaultMulticastRoute != 0)
|
||||
{
|
||||
return m_defaultMulticastRoute;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4StaticRouting::RemoveMulticastRoute(Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface)
|
||||
{
|
||||
//
|
||||
// This method does not attempt to delete the multicast route.
|
||||
//
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin ();
|
||||
i != m_multicastRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
Ipv4MulticastRoute *route = *i;
|
||||
if (origin == route->GetOrigin () &&
|
||||
group == route->GetGroup () &&
|
||||
inputInterface == route->GetInputInterface ())
|
||||
{
|
||||
delete *i;
|
||||
m_multicastRoutes.erase (i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::RemoveMulticastRoute(uint32_t index)
|
||||
{
|
||||
//
|
||||
// From an external point of view the default route appears to be in slot 0
|
||||
// of the routing table. The implementation, however, puts it in a separate
|
||||
// place. So, if a client asks to delete index 0 and we have a default
|
||||
// multicast route set, we have to delete it from that different place
|
||||
// (m_defaultMulticastRoute).
|
||||
//
|
||||
if (index == 0 && m_defaultMulticastRoute != 0)
|
||||
{
|
||||
delete m_defaultMulticastRoute;
|
||||
m_defaultMulticastRoute = 0;
|
||||
}
|
||||
//
|
||||
// If there is a default multicast route present, a client will just assume
|
||||
// that it is in slot zero and there is one "extra" zeroth route in the table.
|
||||
// To return the correct indexed entry in our list, we have to decrement the
|
||||
// index to take into account the default route not being in the actual list.
|
||||
// Since we fell through to here, we've taken care of the case where the
|
||||
// index was zero.
|
||||
//
|
||||
if (m_defaultMulticastRoute != 0)
|
||||
{
|
||||
NS_ASSERT(index > 0);
|
||||
index--;
|
||||
}
|
||||
|
||||
uint32_t tmp = 0;
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin ();
|
||||
i != m_multicastRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete *i;
|
||||
m_multicastRoutes.erase (i);
|
||||
return;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
Ipv4Route *
|
||||
Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
|
||||
{
|
||||
@@ -110,6 +283,110 @@ Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute *
|
||||
Ipv4StaticRouting::LookupStatic (
|
||||
Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t ifIndex)
|
||||
{
|
||||
//
|
||||
// We treat the "any" address (typically 0.0.0.0) as a wildcard in our matching
|
||||
// scheme.
|
||||
//
|
||||
Ipv4Address wildcard = Ipv4Address::GetAny ();
|
||||
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin ();
|
||||
i != m_multicastRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
Ipv4MulticastRoute *route = *i;
|
||||
//
|
||||
// We've been passed an origin address, a multicast group address and an
|
||||
// interface index. We have to decide if the current route in the list is
|
||||
// a match.
|
||||
//
|
||||
// The first case is the restrictive case where the origin, group and index
|
||||
// matches. This picks up exact routes during forwarded and exact routes from
|
||||
// the local node (in which case the ifIndex is a wildcard).
|
||||
//
|
||||
if (origin == route->GetOrigin () && group == route->GetGroup ())
|
||||
{
|
||||
if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY ||
|
||||
ifIndex == route->GetInputInterface ())
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// If the input interface index is not a wildcard (that means that the packet
|
||||
// did not originally come from this node), we're done. We don't
|
||||
// just happily forward packets we don't really know what to do with.
|
||||
// Multicast storms are not generally considered a good thing.
|
||||
//
|
||||
if (ifIndex != Ipv4RoutingProtocol::IF_INDEX_ANY)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// Now, we're going to get a litle less restricive. This only applies in the
|
||||
// case where the packet in question is coming from the local node. In order
|
||||
// to avoid dependencies on the order in which routes were added, we will
|
||||
// actually walk the list two more times, the first time looking for routes
|
||||
// with a single wildcard, and the last time looking for the first route
|
||||
// with two wildcards.
|
||||
//
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin ();
|
||||
i != m_multicastRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
Ipv4MulticastRoute *route = *i;
|
||||
//
|
||||
// Here we will ignore the origin. We know that a single source address must
|
||||
// be picked for a packet, but we may want to send multicast packets out
|
||||
// multiple interfaces. To support this case, a user would need to add
|
||||
// a Multicast route with the route's origin set to wildcard. N.B As a
|
||||
// result, packets sourced from a node with multiple interface may have a
|
||||
// source IP address different from that of the interface actually used to
|
||||
// send the packet.
|
||||
//
|
||||
if (route->GetOrigin () == wildcard && group == route->GetGroup ())
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Finally we want to allow users to specify a default route that specifies
|
||||
// sending all multicast packets out multiple interfaces. The standard
|
||||
// default multicast route is patterned after other systems and limits the
|
||||
// number of outputs to one. If, however a client manually adds a multicast
|
||||
// route with the origin, the multicast group and the input interface index
|
||||
// all set to wildcard, she has created a default route with multiple output
|
||||
// interfaces.
|
||||
//
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin ();
|
||||
i != m_multicastRoutes.end ();
|
||||
i++)
|
||||
{
|
||||
Ipv4MulticastRoute *route = *i;
|
||||
|
||||
if (route->GetOrigin () == wildcard && route->GetGroup () == wildcard)
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
//
|
||||
// We also allow users to specify a typical default multicast route. This
|
||||
// default route is limited to specifying a single output interface.
|
||||
//
|
||||
if (m_defaultMulticastRoute != 0)
|
||||
{
|
||||
return m_defaultMulticastRoute;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4StaticRouting::GetNRoutes (void)
|
||||
{
|
||||
@@ -122,6 +399,20 @@ Ipv4StaticRouting::GetNRoutes (void)
|
||||
n += m_networkRoutes.size ();
|
||||
return n;
|
||||
}
|
||||
|
||||
Ipv4Route *
|
||||
Ipv4StaticRouting::GetDefaultRoute ()
|
||||
{
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
return m_defaultRoute;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Ipv4Route *
|
||||
Ipv4StaticRouting::GetRoute (uint32_t index)
|
||||
{
|
||||
@@ -209,10 +500,52 @@ Ipv4StaticRouting::RemoveRoute (uint32_t index)
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply)
|
||||
Ipv4StaticRouting::RequestRoute (
|
||||
uint32_t ifIndex,
|
||||
Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply)
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (" << &ipHeader << ", " <<
|
||||
&packet << ", " << &routeReply << ")");
|
||||
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): source = " <<
|
||||
ipHeader.GetSource ());
|
||||
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): destination = " <<
|
||||
ipHeader.GetDestination ());
|
||||
|
||||
if (ipHeader.GetDestination ().IsMulticast ())
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination");
|
||||
|
||||
Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
|
||||
ipHeader.GetDestination (), ifIndex);
|
||||
|
||||
if (mRoute)
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): "
|
||||
"Multicast route found");
|
||||
|
||||
for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
|
||||
{
|
||||
Packet p = packet;
|
||||
Ipv4Header h = ipHeader;
|
||||
Ipv4Route route =
|
||||
Ipv4Route::CreateHostRouteTo(h.GetDestination (),
|
||||
mRoute->GetOutputInterface(i));
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): "
|
||||
"Send via interface " << mRoute->GetOutputInterface(i));
|
||||
routeReply (true, route, p, h);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false; // Let other routing protocols try to handle this
|
||||
}
|
||||
//
|
||||
// This is a unicast packet. Check to see if we have a route for it.
|
||||
//
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination");
|
||||
Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
|
||||
if (route != 0)
|
||||
{
|
||||
@@ -226,6 +559,57 @@ Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4StaticRouting::RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex)
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (" << destination << ", " <<
|
||||
&ifIndex << ")");
|
||||
//
|
||||
// First, see if this is a multicast packet we have a route for. If we
|
||||
// have a route, then send the packet down each of the specified interfaces.
|
||||
//
|
||||
if (destination.IsMulticast ())
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): Multicast destination");
|
||||
|
||||
Ipv4MulticastRoute *mRoute = LookupStatic(Ipv4Address::GetAny (),
|
||||
destination, Ipv4RoutingProtocol::IF_INDEX_ANY);
|
||||
|
||||
if (mRoute)
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): "
|
||||
"Multicast route found");
|
||||
|
||||
if (mRoute->GetNOutputInterfaces () != 1)
|
||||
{
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): "
|
||||
"Route is to multiple interfaces. Ignoring.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ifIndex = mRoute->GetOutputInterface(0);
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): "
|
||||
"Found ifIndex " << ifIndex);
|
||||
return true;
|
||||
}
|
||||
return false; // Let other routing protocols try to handle this
|
||||
}
|
||||
//
|
||||
// See if this is a unicast packet we have a route for.
|
||||
//
|
||||
NS_DEBUG ("Ipv4StaticRouting::RequestIfIndex (): Unicast destination");
|
||||
Ipv4Route *route = LookupStatic (destination);
|
||||
if (route)
|
||||
{
|
||||
ifIndex = route->GetInterface ();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4StaticRouting::DoDispose (void)
|
||||
{
|
||||
@@ -246,8 +630,18 @@ Ipv4StaticRouting::DoDispose (void)
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin ();
|
||||
i != m_multicastRoutes.end ();
|
||||
i = m_multicastRoutes.erase (i))
|
||||
{
|
||||
delete (*i);
|
||||
}
|
||||
if (m_defaultMulticastRoute != 0)
|
||||
{
|
||||
delete m_defaultMulticastRoute;
|
||||
m_defaultMulticastRoute = 0;
|
||||
}
|
||||
Ipv4RoutingProtocol::DoDispose ();
|
||||
}
|
||||
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
@@ -45,36 +45,441 @@ class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Static routing protocol for IP version 4 stacks.
|
||||
*
|
||||
* In ns-3 we have the concept of a pluggable routing protocol. Routing
|
||||
* protocols are added to a list maintained by the Ipv4L3Protocol. Every
|
||||
* stack gets one routing protocol for free -- the Ipv4StaticRouting routing
|
||||
* protocol is added in the constructor of the Ipv4L3Protocol (this is the
|
||||
* piece of code that implements the functionality of the IP layer).
|
||||
*
|
||||
* The Ipv4StaticRouting class inherits from the abstract base class
|
||||
* Ipv4RoutingProtocol that defines the interface methods that a routing
|
||||
* protocol must support.
|
||||
*
|
||||
* When a packet arrives in the Ipv4L3Protocol for transmission, it comes
|
||||
* either from a local source via Ipv4L3Protocol::Send or from a remote
|
||||
* source via Ipv4L3Protocol::Forwarding. In both cases, a function is called
|
||||
* (Ipv4L3Protocol::Lookup) to look up the routing information for the packet.
|
||||
*
|
||||
* The lookup function iterates through the list of routing protocols asking
|
||||
* each to see if it can find a route and send the packet. A callback is
|
||||
* provided during each of these calls that should be considered a pre-
|
||||
* packaged send call. This is done to allow asynchronous calls into
|
||||
* routing subsystems in order to support on-demand routing, for example. The
|
||||
* method for requesting this operation is Ipv4StaticRouting::RequestRoute for
|
||||
* the static routing protocol.
|
||||
*
|
||||
* Each routing protocol is also free to implement its own methods for managing
|
||||
* routes which you will find below. This class manages a set of "static" or
|
||||
* manually configured routes for host, network and multicast routes.
|
||||
*
|
||||
* @see Ipv4RoutingProtocol
|
||||
* @see Ipv4L3Protocol::AddRoutingProtocol
|
||||
* @see Ipv4L3Protocol::Ipv4L3Protocol
|
||||
*/
|
||||
class Ipv4StaticRouting : public Ipv4RoutingProtocol
|
||||
{
|
||||
|
||||
public:
|
||||
Ipv4StaticRouting () : m_defaultRoute (0) {}
|
||||
/**
|
||||
* @brief Construct an empty Ipv4StaticRouting routing protocol,
|
||||
* @internal
|
||||
*
|
||||
* The Ipv4StaticRouting class supports host, network and multicast routes.
|
||||
* This method initializes the lists containing these routes to empty.
|
||||
*
|
||||
* @see Ipv4StaticRouting
|
||||
*/
|
||||
Ipv4StaticRouting ();
|
||||
|
||||
virtual bool RequestRoute (Ipv4Header const &ipHeader,
|
||||
/**
|
||||
* @brief Request that a check for a route bw performed and if a route is found
|
||||
* that the packet be sent on its way using the pre-packaged send callback.
|
||||
*
|
||||
* The source and destination IP addresses for the packet in question are found
|
||||
* in the provided Ipv4Header. There are two major processing forks depending
|
||||
* on the type of destination address.
|
||||
*
|
||||
* If the destination address is unicast then the routing table is consulted
|
||||
* for a route to the destination and if it is found, the routeReply callback
|
||||
* is executed to send the packet (with the found route).
|
||||
*
|
||||
* If the destination address is a multicast, then the exact processing steps
|
||||
* depend on whether or not the packet has been sourced locally. This is
|
||||
* determined by the parameter ifIndex. This is the interface index over which
|
||||
* this packet was received. If the packet has not been received over a
|
||||
* network interface, this index will be set to
|
||||
* Ipv4RoutingProtocol::IF_INDEX_ANY (a very large number). In that case,
|
||||
* we want to avoid the requirement that an explicit route out of each node
|
||||
* must be set, so we don't do anything here.
|
||||
*
|
||||
* If the packet is a multicast destination and has been received over a
|
||||
* network interface, a call to this method implies that the packet is being
|
||||
* forwarded. In that case, there must be an explicit route out of the node.
|
||||
* A multicast route references the source address, the destination address
|
||||
* (the multicast group) and the input interface in order to find a route.
|
||||
* We consult the multicast routing table and, if a route is found, send the
|
||||
* packet out of as many interfaces as required using the provided callback
|
||||
* (think of it as a pre-packaged send call).
|
||||
*
|
||||
* @param ifIndex The network interface index over which the packed was
|
||||
* received. If the packet is from a local source, ifIndex will be set to
|
||||
* Ipv4RoutingProtocol::IF_INDEX_ANY.
|
||||
* @param ipHeader the Ipv4Header containing the source and destination IP
|
||||
* addresses for the packet.
|
||||
* @param packet The packet to be sent if a route is found.
|
||||
* @param routeReply A callback that packaged up the call to actually send the
|
||||
* packet.
|
||||
* @return Returns true if a route is found and the packet has been sent,
|
||||
* otherwise returns false indicating that the next routing protocol should
|
||||
* be consulted. In practice, the static routing protocol is the last chance
|
||||
* protocol.
|
||||
*
|
||||
* @see Ipv4StaticRouting
|
||||
* @see Ipv4RoutingProtocol
|
||||
*/
|
||||
virtual bool RequestRoute (uint32_t ifIndex,
|
||||
Ipv4Header const &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply);
|
||||
|
||||
/**
|
||||
* @brief Check to see if we can determine the interface index that will be
|
||||
* used if a packet is sent to this destination.
|
||||
*
|
||||
* This method addresses a problem in the IP stack where a destination address
|
||||
* must be present and checksummed into the IP header before the actual
|
||||
* interface over which the packet is sent can be determined. The answer is
|
||||
* to implement a known and intentional cross-layer violation. This is the
|
||||
* endpoint of a call chain that started up quite high in the stack (sockets)
|
||||
* and has found its way down to the Ipv4L3Protocol which is consulting the
|
||||
* routing protocols for what they would do if presented with a packet of the
|
||||
* given destination.
|
||||
*
|
||||
* Note that the a single interface index is returned. This means that if
|
||||
* the destination address is a multicast, and an explicit route is present
|
||||
* that includeds multiple output interfaces, that route cannot be used.
|
||||
*
|
||||
* If there are multiple paths out of the node, the resolution is performed
|
||||
* by Ipv4L3Protocol::GetIfIndexforDestination which has access to more
|
||||
* contextual information that is useful for making a determination.
|
||||
*
|
||||
* @param destination The Ipv4Address if the destination of a hypothetical
|
||||
* packet. This may be a multicast group address.
|
||||
* @param ifIndex A reference to the interface index over which a packet
|
||||
* sent to this destination would be sent.
|
||||
* @return Returns true if a route is found to the destination that involves
|
||||
* a single output interface index, otherwise returns false indicating that
|
||||
* the next routing protocol should be consulted. In practice, the static
|
||||
* routing protocol is the last chance protocol.
|
||||
*
|
||||
* @see Ipv4StaticRouting
|
||||
* @see Ipv4RoutingProtocol
|
||||
* @see Ipv4L3Protocol
|
||||
*/
|
||||
virtual bool RequestIfIndex (Ipv4Address destination, uint32_t& ifIndex);
|
||||
|
||||
/**
|
||||
* @brief Add a host route to the static routing table.
|
||||
*
|
||||
* @param dest The Ipv4Address destination for this route.
|
||||
* @param nextHop The Ipv4Address of the next hop in the route.
|
||||
* @param interface The network interface index used to send packets to the
|
||||
* destination.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
void AddHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
/**
|
||||
* @brief Add a host route to the static routing table.
|
||||
*
|
||||
* @param dest The Ipv4Address destination for this route.
|
||||
* @param interface The network interface index used to send packets to the
|
||||
* destination.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
void AddHostRouteTo (Ipv4Address dest,
|
||||
uint32_t interface);
|
||||
|
||||
/**
|
||||
* @brief Add a network route to the static routing table.
|
||||
*
|
||||
* @param network The Ipv4Address network for this route.
|
||||
* @param networkmask The Ipv4Mask to extract the network.
|
||||
* @param nextHop The next hop in the route to the destination network.
|
||||
* @param interface The network interface index used to send packets to the
|
||||
* destination.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
void AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
|
||||
/**
|
||||
* @brief Add a network route to the static routing table.
|
||||
*
|
||||
* @param network The Ipv4Address network for this route.
|
||||
* @param networkmask The Ipv4Mask to extract the network.
|
||||
* @param interface The network interface index used to send packets to the
|
||||
* destination.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
void AddNetworkRouteTo (Ipv4Address network,
|
||||
Ipv4Mask networkMask,
|
||||
uint32_t interface);
|
||||
|
||||
/**
|
||||
* @brief Add a default route to the static routing table.
|
||||
*
|
||||
* This method tells the routing system what to do in the case where a specific
|
||||
* route to a destination is not found. The system forwards packets to the
|
||||
* specified node in the hope that it knows better how to route the packet.
|
||||
*
|
||||
* If the default route is set, it is returned as the selected route from
|
||||
* LookupStatic irrespective of destination address if no specific route is
|
||||
* found.
|
||||
*
|
||||
* @param nextHop The Ipv4Address to send packets to in the hope that they
|
||||
* will be forwarded correctly.
|
||||
* @param interface The network interface index used to send packets.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
* @see Ipv4StaticRouting::Lookup
|
||||
*/
|
||||
void SetDefaultRoute (Ipv4Address nextHop,
|
||||
uint32_t interface);
|
||||
|
||||
/**
|
||||
* @brief Get the number of individual unicast routes that have been added
|
||||
* to the routing table.
|
||||
*
|
||||
* @warning The default route counts as one of the routes.
|
||||
*/
|
||||
uint32_t GetNRoutes (void);
|
||||
|
||||
/**
|
||||
* @brief Get the default route from the static routing table.
|
||||
*
|
||||
* @return If the default route is set, a pointer to that Ipv4Route is
|
||||
* returned, otherwise a zero pointer is returned.
|
||||
*
|
||||
* @see Ipv4Route
|
||||
*/
|
||||
Ipv4Route *GetDefaultRoute (void);
|
||||
|
||||
/**
|
||||
* @brief Get a route from the static unicast routing table.
|
||||
*
|
||||
* Externally, the unicast static routing table appears simply as a table with
|
||||
* n entries. The one sublety of note is that if a default route has been set
|
||||
* it will appear as the zeroth entry in the table. This means that if you
|
||||
* add only a default route, the table will have one entry that can be accessed
|
||||
* either by explicity calling GetDefaultRoute () or by calling GetRoute (0).
|
||||
*
|
||||
* Similarly, if the default route has been set, calling RemoveRoute (0) will
|
||||
* remove the default route.
|
||||
*
|
||||
* @param i The index (into the routing table) of the route to retrieve. If
|
||||
* the default route has been set, it will occupy index zero.
|
||||
* @return If route is set, a pointer to that Ipv4Route is returned, otherwise
|
||||
* a zero pointer is returned.
|
||||
*
|
||||
* @see Ipv4Route
|
||||
* @see Ipv4StaticRouting::RemoveRoute
|
||||
*/
|
||||
Ipv4Route *GetRoute (uint32_t i);
|
||||
|
||||
/**
|
||||
* @brief Remove a route from the static unicast routing table.
|
||||
*
|
||||
* Externally, the unicast static routing table appears simply as a table with
|
||||
* n entries. The one sublety of note is that if a default route has been set
|
||||
* it will appear as the zeroth entry in the table. This means that if the
|
||||
* default route has been set, calling RemoveRoute (0) will remove the
|
||||
* default route.
|
||||
*
|
||||
* @param i The index (into the routing table) of the route to remove. If
|
||||
* the default route has been set, it will occupy index zero.
|
||||
*
|
||||
* @see Ipv4Route
|
||||
* @see Ipv4StaticRouting::GetRoute
|
||||
* @see Ipv4StaticRouting::AddRoute
|
||||
*/
|
||||
void RemoveRoute (uint32_t i);
|
||||
|
||||
/**
|
||||
* @brief Add a multicast route to the static routing table.
|
||||
*
|
||||
* A multicast route must specify an origin IP address, a multicast group and
|
||||
* an input network interface index as conditions and provide a vector of
|
||||
* output network interface indices over which packets matching the conditions
|
||||
* are sent.
|
||||
*
|
||||
* Typically there are two main types of multicast routes: routes of the
|
||||
* first kind are used during forwarding. All of the conditions must be
|
||||
* exlicitly provided. The second kind of routes are used to get packets off
|
||||
* of a local node. The difference is in the input interface. Routes for
|
||||
* forwarding will always have an explicit input interface specified. Routes
|
||||
* off of a node will always set the input interface to a wildcard specified
|
||||
* by the index Ipv4RoutingProtocol::IF_INDEX_ANY.
|
||||
*
|
||||
* For routes off of a local node wildcards may be used in the origin and
|
||||
* multicast group addresses. The wildcard used for Ipv4Adresses is that
|
||||
* address returned by Ipv4Address::GetAny () -- typically "0.0.0.0". Usage
|
||||
* of a wildcard allows one to specify default behavior to varying degrees.
|
||||
*
|
||||
* For example, making the origin address a wildcard, but leaving the
|
||||
* multicast group specific allows one (in the case of a node with multiple
|
||||
* interfaces) to create different routes using different output interfaces
|
||||
* for each multicast group.
|
||||
*
|
||||
* If the origin and multicast addresses are made wildcards, you have created
|
||||
* essentially a default multicast address that can forward to multiple
|
||||
* interfaces. Compare this to the actual default multicast address that is
|
||||
* limited to specifying a single output interface for compatibility with
|
||||
* existing functionality in other systems.
|
||||
*
|
||||
* @param origin The Ipv4Address of the origin of packets for this route. May
|
||||
* be Ipv4Address:GetAny for open groups.
|
||||
* @param group The Ipv4Address of the multicast group or this route.
|
||||
* @param inputInterface The input network interface index over which to
|
||||
* expect packets destined for this route. May be
|
||||
* Ipv4RoutingProtocol::IF_INDEX_ANY for packets of local origin.
|
||||
* @param outputInterface A vector of network interface indices used to specify
|
||||
* how to send packets to the destination(s).
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
void AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces);
|
||||
|
||||
/**
|
||||
* @brief Add a default multicast route to the static routing table.
|
||||
*
|
||||
* This is the multicast equivalent of the unicast version SetDefaultRoute.
|
||||
* We tell the routing system what to do in the case where a specific route
|
||||
* to a destination multicast group is not found. The system forwards
|
||||
* packets out the specified interface in the hope that "something out there"
|
||||
* knows better how to route the packet. This method is only used in
|
||||
* initially sending packets off of a host. The default multicast route is
|
||||
* not consulted during forwarding -- exact routes must be specified using
|
||||
* AddMulticastRoute for that case.
|
||||
*
|
||||
* Since we're basically sending packets to some entity we think may know
|
||||
* better what to do, we don't pay attention to "subtleties" like origin
|
||||
* address, nor do we worry about forwarding out multiple interfaces. If the
|
||||
* default multicast route is set, it is returned as the selected route from
|
||||
* LookupStatic irrespective of origin or multicast group if another specific
|
||||
* route is not found.
|
||||
*
|
||||
* @param outputInterface The network interface index used to specify where
|
||||
* to send packets in the case of unknown routes.
|
||||
*
|
||||
* @see Ipv4Address
|
||||
*/
|
||||
void SetDefaultMulticastRoute (uint32_t outputInterface);
|
||||
|
||||
/**
|
||||
* @brief Get the number of individual multicast routes that have been added
|
||||
* to the routing table.
|
||||
*
|
||||
* @warning The default multicast route counts as one of the routes.
|
||||
*/
|
||||
uint32_t GetNMulticastRoutes (void) const;
|
||||
|
||||
/**
|
||||
* @brief Get a route from the static multicast routing table.
|
||||
*
|
||||
* Externally, the multicast static routing table appears simply as a table
|
||||
* with n entries. The one sublety of note is that if a default route has
|
||||
* been set it will appear as the zeroth entry in the table. This means that
|
||||
* if you add only a default route, the table will have one entry that can be
|
||||
* accessed either by explicity calling GetDefaultMulticastRoute () or by
|
||||
* calling GetMulticastRoute (0).
|
||||
*
|
||||
* Similarly, if the default route has been set, calling
|
||||
* RemoveMulticastRoute (0) will remove the default route.
|
||||
*
|
||||
* @param i The index (into the routing table) of the multicast route to
|
||||
* retrieve. If the default route has been set, it will occupy index zero.
|
||||
* @return If route <i> is set, a pointer to that Ipv4MulticastRoute is
|
||||
* returned, otherwise a zero pointer is returned.
|
||||
*
|
||||
* @see Ipv4MulticastRoute
|
||||
* @see Ipv4StaticRouting::RemoveRoute
|
||||
*/
|
||||
Ipv4MulticastRoute *GetMulticastRoute (uint32_t i) const;
|
||||
|
||||
/**
|
||||
* @brief Get the default multicast route from the static routing table.
|
||||
*
|
||||
* @return If the default route is set, a pointer to that Ipv4MulticastRoute is
|
||||
* returned, otherwise a zero pointer is returned.
|
||||
*
|
||||
* @see Ipv4Route
|
||||
*/
|
||||
Ipv4MulticastRoute *GetDefaultMulticastRoute (void) const;
|
||||
|
||||
/**
|
||||
* @brief Remove a route from the static multicast routing table.
|
||||
*
|
||||
* Externally, the multicast static routing table appears simply as a table
|
||||
* with n entries. The one sublety of note is that if a default multicast
|
||||
* route has been set it will appear as the zeroth entry in the table. This
|
||||
* means that the default route may be removed by calling this method with
|
||||
* appropriate wildcard parameters.
|
||||
*
|
||||
* This method causes the multicast routing table to be searched for the first
|
||||
* route that matches the parameters and removes it.
|
||||
*
|
||||
* Wildcards may be provided to this function, but the wildcards are used to
|
||||
* exacly match wildcards in the routes (see AddMulticastRoute). That is,
|
||||
* calling RemoveMulticastRoute with the origin set to "0.0.0.0" will not
|
||||
* remove routes with any address in the origin, but will only remove routes
|
||||
* with "0.0.0.0" set as the the origin.
|
||||
*
|
||||
* @param origin The IP address specified as the origin of packets for the
|
||||
* route.
|
||||
* @param origin The IP address specified as the multicast group addres of
|
||||
* the route.
|
||||
* @param inputInterfade The network interface index specified as the expected
|
||||
* input interface for the route.
|
||||
* @returns True if a route was found and removed, false otherwise.
|
||||
*
|
||||
* @see Ipv4MulticastRoute
|
||||
* @see Ipv4StaticRouting::AddMulticastRoute
|
||||
*/
|
||||
bool RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface);
|
||||
|
||||
/**
|
||||
* @brief Remove a route from the static multicast routing table.
|
||||
*
|
||||
* Externally, the multicast static routing table appears simply as a table
|
||||
* with n entries. The one sublety of note is that if a default multicast
|
||||
* route has been set it will appear as the zeroth entry in the table. This
|
||||
* means that if the default route has been set, calling
|
||||
* RemoveMulticastRoute (0) will remove the default route.
|
||||
*
|
||||
* @param index The index (into the multicast routing table) of the route to
|
||||
* remove. If the default route has been set, it will occupy index zero.
|
||||
*
|
||||
* @see Ipv4Route
|
||||
* @see Ipv4StaticRouting::GetRoute
|
||||
* @see Ipv4StaticRouting::AddRoute
|
||||
*/
|
||||
void RemoveMulticastRoute (uint32_t index);
|
||||
|
||||
protected:
|
||||
void DoDispose (void);
|
||||
|
||||
@@ -86,15 +491,21 @@ private:
|
||||
typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
|
||||
typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
|
||||
|
||||
typedef std::list<Ipv4MulticastRoute *> MulticastRoutes;
|
||||
typedef std::list<Ipv4MulticastRoute *>::const_iterator MulticastRoutesCI;
|
||||
typedef std::list<Ipv4MulticastRoute *>::iterator MulticastRoutesI;
|
||||
|
||||
Ipv4Route *LookupStatic (Ipv4Address dest);
|
||||
Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group,
|
||||
uint32_t ifIndex);
|
||||
|
||||
HostRoutes m_hostRoutes;
|
||||
NetworkRoutes m_networkRoutes;
|
||||
Ipv4Route *m_defaultRoute;
|
||||
Ipv4MulticastRoute *m_defaultMulticastRoute;
|
||||
MulticastRoutes m_multicastRoutes;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // Namespace ns3
|
||||
|
||||
#endif /* IPV4_STATIC_ROUTING_H */
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/node.h"
|
||||
@@ -30,6 +31,8 @@
|
||||
#include "ipv4-l3-protocol.h"
|
||||
#include "udp-socket.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("UdpL4Protocol");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/* see http://www.iana.org/assignments/protocol-numbers */
|
||||
@@ -39,14 +42,19 @@ UdpL4Protocol::UdpL4Protocol (Ptr<Node> node)
|
||||
: Ipv4L4Protocol (PROT_NUMBER, 2),
|
||||
m_node (node),
|
||||
m_endPoints (new Ipv4EndPointDemux ())
|
||||
{}
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::UdpL4Protocol ()");
|
||||
}
|
||||
|
||||
UdpL4Protocol::~UdpL4Protocol ()
|
||||
{}
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::~UdpL4Protocol ()");
|
||||
}
|
||||
|
||||
void
|
||||
UdpL4Protocol::DoDispose (void)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::DoDispose ()");
|
||||
if (m_endPoints != 0)
|
||||
{
|
||||
delete m_endPoints;
|
||||
@@ -59,6 +67,7 @@ UdpL4Protocol::DoDispose (void)
|
||||
Ptr<Socket>
|
||||
UdpL4Protocol::CreateSocket (void)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::CreateSocket ()");
|
||||
Ptr<Socket> socket = Create<UdpSocket> (m_node, this);
|
||||
return socket;
|
||||
}
|
||||
@@ -66,27 +75,36 @@ UdpL4Protocol::CreateSocket (void)
|
||||
Ipv4EndPoint *
|
||||
UdpL4Protocol::Allocate (void)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Allocate ()");
|
||||
return m_endPoints->Allocate ();
|
||||
}
|
||||
|
||||
Ipv4EndPoint *
|
||||
UdpL4Protocol::Allocate (Ipv4Address address)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Allocate (" << address << ")");
|
||||
return m_endPoints->Allocate (address);
|
||||
}
|
||||
|
||||
Ipv4EndPoint *
|
||||
UdpL4Protocol::Allocate (uint16_t port)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Allocate (" << port << ")");
|
||||
return m_endPoints->Allocate (port);
|
||||
}
|
||||
|
||||
Ipv4EndPoint *
|
||||
UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Allocate (" << address << ", " << port << ")");
|
||||
return m_endPoints->Allocate (address, port);
|
||||
}
|
||||
Ipv4EndPoint *
|
||||
UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
|
||||
Ipv4Address peerAddress, uint16_t peerPort)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Allocate (" << localAddress << ", " << localPort <<
|
||||
", " << peerAddress << ", " << peerPort << ")");
|
||||
return m_endPoints->Allocate (localAddress, localPort,
|
||||
peerAddress, peerPort);
|
||||
}
|
||||
@@ -94,6 +112,7 @@ UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
|
||||
void
|
||||
UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Deallocate (" << endPoint << ")");
|
||||
m_endPoints->DeAllocate (endPoint);
|
||||
}
|
||||
|
||||
@@ -102,6 +121,9 @@ UdpL4Protocol::Receive(Packet& packet,
|
||||
Ipv4Address const &source,
|
||||
Ipv4Address const &destination)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Receive (" << &packet << ", " << source <<
|
||||
", " << destination << ")");
|
||||
|
||||
UdpHeader udpHeader;
|
||||
packet.RemoveHeader (udpHeader);
|
||||
Ipv4EndPointDemux::EndPoints endPoints =
|
||||
@@ -119,6 +141,9 @@ UdpL4Protocol::Send (Packet packet,
|
||||
Ipv4Address saddr, Ipv4Address daddr,
|
||||
uint16_t sport, uint16_t dport)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Send (" << &packet << ", " << saddr <<
|
||||
", " << daddr << ", " << sport << ", " << dport << ")");
|
||||
|
||||
UdpHeader udpHeader;
|
||||
udpHeader.SetDestination (dport);
|
||||
udpHeader.SetSource (sport);
|
||||
@@ -132,6 +157,7 @@ UdpL4Protocol::Send (Packet packet,
|
||||
Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
|
||||
if (ipv4 != 0)
|
||||
{
|
||||
NS_DEBUG("UdpL4Protocol::Send (): Sending to IP");
|
||||
ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
*
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
@@ -26,6 +28,9 @@
|
||||
#include "udp-l4-protocol.h"
|
||||
#include "ipv4-end-point.h"
|
||||
#include "ipv4-l4-demux.h"
|
||||
#include "ns3/ipv4.h"
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("UdpSocket");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -37,9 +42,14 @@ UdpSocket::UdpSocket (Ptr<Node> node, Ptr<UdpL4Protocol> udp)
|
||||
m_shutdownSend (false),
|
||||
m_shutdownRecv (false),
|
||||
m_connected (false)
|
||||
{}
|
||||
{
|
||||
NS_DEBUG("UdpSocket::UdpSocket ()");
|
||||
}
|
||||
|
||||
UdpSocket::~UdpSocket ()
|
||||
{
|
||||
NS_DEBUG("UdpSocket::~UdpSocket ()");
|
||||
|
||||
m_node = 0;
|
||||
if (m_endPoint != 0)
|
||||
{
|
||||
@@ -62,25 +72,32 @@ UdpSocket::~UdpSocket ()
|
||||
enum Socket::SocketErrno
|
||||
UdpSocket::GetErrno (void) const
|
||||
{
|
||||
NS_DEBUG("UdpSocket::GetErrno ()");
|
||||
|
||||
return m_errno;
|
||||
}
|
||||
|
||||
Ptr<Node>
|
||||
UdpSocket::GetNode (void) const
|
||||
{
|
||||
NS_DEBUG("UdpSocket::GetNode ()");
|
||||
return m_node;
|
||||
}
|
||||
|
||||
void
|
||||
UdpSocket::Destroy (void)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::Destroy ()");
|
||||
m_node = 0;
|
||||
m_endPoint = 0;
|
||||
m_udp = 0;
|
||||
}
|
||||
|
||||
int
|
||||
UdpSocket::FinishBind (void)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::FinishBind ()");
|
||||
|
||||
if (m_endPoint == 0)
|
||||
{
|
||||
return -1;
|
||||
@@ -93,14 +110,20 @@ UdpSocket::FinishBind (void)
|
||||
int
|
||||
UdpSocket::Bind (void)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::Bind ()");
|
||||
|
||||
m_endPoint = m_udp->Allocate ();
|
||||
return FinishBind ();
|
||||
}
|
||||
|
||||
int
|
||||
UdpSocket::Bind (const Address &address)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::Bind (" << address << ")");
|
||||
|
||||
if (!InetSocketAddress::IsMatchingType (address))
|
||||
{
|
||||
NS_DEBUG("UdpSocket::Bind (): Not IsMatchingType");
|
||||
return ERROR_INVAL;
|
||||
}
|
||||
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
|
||||
@@ -129,12 +152,15 @@ UdpSocket::Bind (const Address &address)
|
||||
int
|
||||
UdpSocket::ShutdownSend (void)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::ShutDownSend ()");
|
||||
m_shutdownSend = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
UdpSocket::ShutdownRecv (void)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::ShutDownRecv ()");
|
||||
m_shutdownRecv = false;
|
||||
return 0;
|
||||
}
|
||||
@@ -142,6 +168,7 @@ UdpSocket::ShutdownRecv (void)
|
||||
int
|
||||
UdpSocket::Close(void)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::Close ()");
|
||||
NotifyCloseCompleted ();
|
||||
return 0;
|
||||
}
|
||||
@@ -149,24 +176,36 @@ UdpSocket::Close(void)
|
||||
int
|
||||
UdpSocket::Connect(const Address & address)
|
||||
{
|
||||
NS_DEBUG ("UdpSocket::Connect (" << address << ")");
|
||||
Ipv4Route routeToDest;
|
||||
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
|
||||
m_defaultAddress = transport.GetIpv4 ();
|
||||
m_defaultPort = transport.GetPort ();
|
||||
NotifyConnectionSucceeded ();
|
||||
m_connected = true;
|
||||
if (GetIpv4RouteToDestination (m_node, routeToDest, m_defaultAddress) )
|
||||
|
||||
NS_DEBUG ("UdpSocket::Connect (): Updating local address");
|
||||
|
||||
uint32_t localIfIndex;
|
||||
|
||||
Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
|
||||
if (ipv4->GetIfIndexForDestination (m_defaultAddress, localIfIndex))
|
||||
{
|
||||
uint32_t localIfIndex = routeToDest.GetInterface ();
|
||||
Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
m_endPoint->SetLocalAddress (ipv4->GetAddress(localIfIndex) );
|
||||
m_endPoint->SetLocalAddress (ipv4->GetAddress(localIfIndex));
|
||||
}
|
||||
|
||||
NS_DEBUG ("UdpSocket::Connect (): Local address is " <<
|
||||
m_endPoint->GetLocalAddress());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
UdpSocket::Send (const Packet &p)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::Send (" << &p << ")");
|
||||
|
||||
if (!m_connected)
|
||||
{
|
||||
m_errno = ERROR_NOTCONN;
|
||||
@@ -196,12 +235,14 @@ UdpSocket::DoSend (const Packet &p)
|
||||
return DoSendTo (p, m_defaultAddress, m_defaultPort);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
UdpSocket::DoSendTo (const Packet &p, const Address &address)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << address << ")");
|
||||
|
||||
if (!m_connected)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::DoSendTo (): Not connected");
|
||||
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
|
||||
Ipv4Address ipv4 = transport.GetIpv4 ();
|
||||
uint16_t port = transport.GetPort ();
|
||||
@@ -210,13 +251,19 @@ UdpSocket::DoSendTo (const Packet &p, const Address &address)
|
||||
else
|
||||
{
|
||||
// connected UDP socket must use default addresses
|
||||
NS_DEBUG("UdpSocket::DoSendTo (): Connected");
|
||||
return DoSendTo (p, m_defaultAddress, m_defaultPort);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::DoSendTo (" << &p << ", " << dest << ", " <<
|
||||
port << ")");
|
||||
|
||||
Ipv4Route routeToDest;
|
||||
|
||||
if (m_endPoint == 0)
|
||||
{
|
||||
if (Bind () == -1)
|
||||
@@ -231,13 +278,17 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port)
|
||||
m_errno = ERROR_SHUTDOWN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t localIfIndex;
|
||||
Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
|
||||
//
|
||||
// If dest is sent to the limited broadcast address (all ones),
|
||||
// convert it to send a copy of the packet out of every interface
|
||||
//
|
||||
if (dest.IsBroadcast ())
|
||||
{
|
||||
Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_DEBUG("UdpSocket::DoSendTo (): Limited broadcast");
|
||||
for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
|
||||
{
|
||||
Ipv4Address addri = ipv4->GetAddress (i);
|
||||
@@ -247,10 +298,9 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port)
|
||||
NotifyDataSent (p.GetSize ());
|
||||
}
|
||||
}
|
||||
else if (GetIpv4RouteToDestination (m_node, routeToDest, dest) )
|
||||
else if (ipv4->GetIfIndexForDestination(dest, localIfIndex))
|
||||
{
|
||||
uint32_t localIfIndex = routeToDest.GetInterface ();
|
||||
Ptr<Ipv4> ipv4 = m_node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_DEBUG("UdpSocket::DoSendTo (): Route exists");
|
||||
m_udp->Send (p, ipv4->GetAddress (localIfIndex), dest,
|
||||
m_endPoint->GetLocalPort (), port);
|
||||
NotifyDataSent (p.GetSize ());
|
||||
@@ -258,15 +308,18 @@ UdpSocket::DoSendTo (const Packet &p, Ipv4Address dest, uint16_t port)
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_DEBUG("UdpSocket::DoSendTo (): ERROR_NOROUTETOHOST");
|
||||
m_errno = ERROR_NOROUTETOHOST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
UdpSocket::SendTo(const Address &address, const Packet &p)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::SendTo (" << address << ", " << &p << ")");
|
||||
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
|
||||
Ipv4Address ipv4 = transport.GetIpv4 ();
|
||||
uint16_t port = transport.GetPort ();
|
||||
@@ -276,6 +329,9 @@ UdpSocket::SendTo(const Address &address, const Packet &p)
|
||||
void
|
||||
UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port)
|
||||
{
|
||||
NS_DEBUG("UdpSocket::ForwardUp (" << &packet << ", " << ipv4 << ", " <<
|
||||
port << ")");
|
||||
|
||||
if (m_shutdownRecv)
|
||||
{
|
||||
return;
|
||||
@@ -286,4 +342,4 @@ UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port)
|
||||
NotifyDataReceived (p, address);
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
} //namespace ns3
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006,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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006,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
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* -*- 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 "position.h"
|
||||
#include <cmath>
|
||||
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
/* -*- 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 POSITION_H
|
||||
#define POSITION_H
|
||||
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* -*- 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 "random-position.h"
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/default-value.h"
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
/* -*- 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 RANDOM_POSITION_H
|
||||
#define RANDOM_POSITION_H
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- 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
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* -*- 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 "speed.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
/* -*- 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 SPEED_H
|
||||
#define SPEED_H
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006 INRIA
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006,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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006,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
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006,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 "ns3/simulator.h"
|
||||
#include "ns3/rectangle.h"
|
||||
#include "static-speed-helper.h"
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006,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 STATIC_SPEED_HELPER_H
|
||||
#define STATIC_SPEED_HELPER_H
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006, 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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2006, 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
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace ns3 {
|
||||
|
||||
Ipv4Route::Ipv4Route ()
|
||||
{}
|
||||
|
||||
Ipv4Route::Ipv4Route (Ipv4Route const &route)
|
||||
: m_dest (route.m_dest),
|
||||
m_destNetworkMask (route.m_destNetworkMask),
|
||||
@@ -37,6 +38,13 @@ Ipv4Route::Ipv4Route (Ipv4Route const &route)
|
||||
m_interface (route.m_interface)
|
||||
{}
|
||||
|
||||
Ipv4Route::Ipv4Route (Ipv4Route const *route)
|
||||
: m_dest (route->m_dest),
|
||||
m_destNetworkMask (route->m_destNetworkMask),
|
||||
m_gateway (route->m_gateway),
|
||||
m_interface (route->m_interface)
|
||||
{}
|
||||
|
||||
Ipv4Route::Ipv4Route (Ipv4Address dest,
|
||||
Ipv4Address gateway,
|
||||
uint32_t interface)
|
||||
@@ -137,7 +145,6 @@ Ipv4Route::GetInterface (void) const
|
||||
return m_interface;
|
||||
}
|
||||
|
||||
|
||||
Ipv4Route
|
||||
Ipv4Route::CreateHostRouteTo (Ipv4Address dest,
|
||||
Ipv4Address nextHop,
|
||||
@@ -220,4 +227,108 @@ std::ostream& operator<< (std::ostream& os, Ipv4Route const& route)
|
||||
return os;
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Ipv4MulticastRoute
|
||||
*****************************************************/
|
||||
|
||||
Ipv4MulticastRoute::Ipv4MulticastRoute ()
|
||||
{
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute::Ipv4MulticastRoute (Ipv4MulticastRoute const &route)
|
||||
:
|
||||
m_origin (route.m_origin),
|
||||
m_group (route.m_group),
|
||||
m_inputInterface (route.m_inputInterface),
|
||||
m_outputInterfaces (route.m_outputInterfaces)
|
||||
{
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute::Ipv4MulticastRoute (Ipv4MulticastRoute const *route)
|
||||
:
|
||||
m_origin (route->m_origin),
|
||||
m_group (route->m_group),
|
||||
m_inputInterface (route->m_inputInterface),
|
||||
m_outputInterfaces (route->m_outputInterfaces)
|
||||
{
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute::Ipv4MulticastRoute (
|
||||
Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces)
|
||||
{
|
||||
m_origin = origin;
|
||||
m_group = group;
|
||||
m_inputInterface = inputInterface;
|
||||
m_outputInterfaces = outputInterfaces;
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4MulticastRoute::GetOrigin (void) const
|
||||
{
|
||||
return m_origin;
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4MulticastRoute::GetGroup (void) const
|
||||
{
|
||||
return m_group;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4MulticastRoute::GetInputInterface (void) const
|
||||
{
|
||||
return m_inputInterface;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4MulticastRoute::GetNOutputInterfaces (void) const
|
||||
{
|
||||
return m_outputInterfaces.size ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4MulticastRoute::GetOutputInterface (uint32_t n) const
|
||||
{
|
||||
NS_ASSERT_MSG(n < m_outputInterfaces.size (),
|
||||
"Ipv4MulticastRoute::GetOutputInterface (): index out of bounds");
|
||||
|
||||
return m_outputInterfaces[n];
|
||||
}
|
||||
|
||||
std::vector<uint32_t>
|
||||
Ipv4MulticastRoute::GetOutputInterfaces (void) const
|
||||
{
|
||||
return m_outputInterfaces;
|
||||
}
|
||||
|
||||
Ipv4MulticastRoute
|
||||
Ipv4MulticastRoute::CreateMulticastRoute (
|
||||
Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces)
|
||||
{
|
||||
return Ipv4MulticastRoute (origin, group, inputInterface, outputInterfaces);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<< (std::ostream& os, Ipv4MulticastRoute const& route)
|
||||
{
|
||||
os << "origin=" << route.GetOrigin () <<
|
||||
", group=" << route.GetGroup () <<
|
||||
", input interface=" << route.GetInputInterface () <<
|
||||
", output interfaces=";
|
||||
|
||||
for (uint32_t i = 0; i < route.GetNOutputInterfaces (); ++i)
|
||||
{
|
||||
os << route.GetOutputInterface (i) << " ";
|
||||
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define IPV4_ROUTE_H
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
#include "ipv4-address.h"
|
||||
@@ -36,12 +37,19 @@ public:
|
||||
* \brief This constructor does nothing
|
||||
*/
|
||||
Ipv4Route ();
|
||||
|
||||
/**
|
||||
* \brief Copy Constructor
|
||||
* \param route The route to copy
|
||||
*/
|
||||
Ipv4Route (Ipv4Route const &route);
|
||||
|
||||
/**
|
||||
* \brief Copy Constructor
|
||||
* \param route The route to copy
|
||||
*/
|
||||
Ipv4Route (Ipv4Route const *route);
|
||||
|
||||
bool IsHost (void) const;
|
||||
/**
|
||||
* \return The IPv4 address of the destination of this route
|
||||
@@ -98,6 +106,74 @@ private:
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, Ipv4Route const& route);
|
||||
|
||||
/**
|
||||
* \brief A record of an IPv4 multicast route
|
||||
*/
|
||||
class Ipv4MulticastRoute {
|
||||
public:
|
||||
/**
|
||||
* \brief This constructor does nothing
|
||||
*/
|
||||
Ipv4MulticastRoute ();
|
||||
|
||||
/**
|
||||
* \brief Copy Constructor
|
||||
* \param route The route to copy
|
||||
*/
|
||||
Ipv4MulticastRoute (Ipv4MulticastRoute const &route);
|
||||
|
||||
/**
|
||||
* \brief Copy Constructor
|
||||
* \param route The route to copy
|
||||
*/
|
||||
Ipv4MulticastRoute (Ipv4MulticastRoute const *route);
|
||||
|
||||
/**
|
||||
* \return The IPv4 address of the source of this route
|
||||
*/
|
||||
Ipv4Address GetOrigin (void) const;
|
||||
|
||||
/**
|
||||
* \return The IPv4 address of the multicast group of this route
|
||||
*/
|
||||
Ipv4Address GetGroup (void) const;
|
||||
|
||||
/**
|
||||
* \return The IPv4 address of the input interface of this route
|
||||
*/
|
||||
uint32_t GetInputInterface (void) const;
|
||||
|
||||
/**
|
||||
* \return The number of output interfaces of this route
|
||||
*/
|
||||
uint32_t GetNOutputInterfaces (void) const;
|
||||
|
||||
/**
|
||||
* \return A specified output interface.
|
||||
*/
|
||||
uint32_t GetOutputInterface (uint32_t n) const;
|
||||
|
||||
/**
|
||||
* \return A vector of all of the output interfaces of this route.
|
||||
*/
|
||||
std::vector<uint32_t> GetOutputInterfaces (void) const;
|
||||
|
||||
static Ipv4MulticastRoute CreateMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group, uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces);
|
||||
|
||||
private:
|
||||
Ipv4MulticastRoute (Ipv4Address origin, Ipv4Address group,
|
||||
uint32_t inputInterface, std::vector<uint32_t> outputInterfaces);
|
||||
|
||||
Ipv4Address m_origin;
|
||||
Ipv4Address m_group;
|
||||
uint32_t m_inputInterface;
|
||||
std::vector<uint32_t> m_outputInterfaces;
|
||||
};
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, Ipv4MulticastRoute const& route);
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
#endif /* IPV4_ROUTE_H */
|
||||
|
||||
@@ -36,10 +36,10 @@ Ipv4::~Ipv4 ()
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
GetIfIndexByIpv4Address (Ptr<Node> node, Ipv4Address a, Ipv4Mask amask)
|
||||
Ipv4::GetIfIndexByAddress (Ptr<Node> node, Ipv4Address a, Ipv4Mask amask)
|
||||
{
|
||||
Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_ASSERT_MSG (ipv4, "GetIfIndexByIpv4Address: No Ipv4 interface");
|
||||
NS_ASSERT_MSG (ipv4, "Ipv4::GetIfIndexByAddress: No Ipv4 interface");
|
||||
for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
|
||||
{
|
||||
if (ipv4->GetAddress (i).CombineMask(amask) == a.CombineMask(amask) )
|
||||
@@ -48,17 +48,26 @@ GetIfIndexByIpv4Address (Ptr<Node> node, Ipv4Address a, Ipv4Mask amask)
|
||||
}
|
||||
}
|
||||
// Mapping not found
|
||||
NS_ASSERT_MSG (false, "GetIfIndexByIpv4Address failed");
|
||||
NS_ASSERT_MSG (false, "Ipv4::GetIfIndexByAddress failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// XXX BUGBUG I don't think this is really the right approach here. The call
|
||||
// to GetRoute () filters down into Ipv4L3Protocol where it translates into
|
||||
// a call into the Ipv4 static routing package. This bypasses any other
|
||||
// routing packages. At a minimum, the name is misleading.
|
||||
//
|
||||
bool
|
||||
GetIpv4RouteToDestination (Ptr<Node> node, Ipv4Route& route,
|
||||
Ipv4Address a, Ipv4Mask amask)
|
||||
Ipv4::GetRouteToDestination (
|
||||
Ptr<Node> node,
|
||||
Ipv4Route& route,
|
||||
Ipv4Address a,
|
||||
Ipv4Mask amask)
|
||||
{
|
||||
Ipv4Route tempRoute;
|
||||
Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
NS_ASSERT_MSG (ipv4, "GetIpv4RouteToDestination: No Ipv4 interface");
|
||||
NS_ASSERT_MSG (ipv4, "Ipv4::GetRouteToDestination: No Ipv4 interface");
|
||||
for (uint32_t i = 0; i < ipv4->GetNRoutes (); i++)
|
||||
{
|
||||
tempRoute = ipv4->GetRoute (i);
|
||||
@@ -83,5 +92,4 @@ GetIpv4RouteToDestination (Ptr<Node> node, Ipv4Route& route,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
178
src/node/ipv4.h
178
src/node/ipv4.h
@@ -71,6 +71,7 @@ public:
|
||||
/**
|
||||
* \brief Asynchronously requests a route for a given packet and IP header
|
||||
*
|
||||
* \param ifIndex The interface index on which the packet was received.
|
||||
* \param ipHeader IP header of the packet
|
||||
* \param packet packet that is being sent or forwarded
|
||||
* \param routeReply callback that will receive the route reply
|
||||
@@ -100,9 +101,47 @@ public:
|
||||
* immediately after the IP header, although most routing do not
|
||||
* insert any extra header.
|
||||
*/
|
||||
virtual bool RequestRoute (const Ipv4Header &ipHeader,
|
||||
virtual bool RequestRoute (uint32_t ifIndex,
|
||||
const Ipv4Header &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply) = 0;
|
||||
|
||||
/**
|
||||
* \brief Synchronously check to see if we can determine the interface index
|
||||
* that will be used if a packet is sent to this destination.
|
||||
*
|
||||
* This method addresses a problem in the IP stack where a destination address
|
||||
* must be present and checksummed into the IP header before the actual
|
||||
* interface over which the packet is sent can be determined. The answer is
|
||||
* to implement a known and intentional cross-layer violation. This is the
|
||||
* endpoint of a call chain that started up quite high in the stack (sockets)
|
||||
* and has found its way down to the Ipv4L3Protocol which is consulting the
|
||||
* routing protocols for what they would do if presented with a packet of the
|
||||
* given destination.
|
||||
*
|
||||
* Note that the a single interface index is returned. This means that if
|
||||
* the destination address is a multicast, and an explicit route is present
|
||||
* that includeds multiple output interfaces, that route cannot be used.
|
||||
*
|
||||
* If there are multiple paths out of the node, the resolution is performed
|
||||
* by Ipv4L3Protocol::GetIfIndexforDestination which has access to more
|
||||
* contextual information that is useful for making a determination.
|
||||
*
|
||||
* \param destination The Ipv4Address if the destination of a hypothetical
|
||||
* packet. This may be a multicast group address.
|
||||
* \param ifIndex A reference to the interface index over which a packet
|
||||
* sent to this destination would be sent.
|
||||
* \return Returns true if a route is found to the destination that involves
|
||||
* a single output interface index, otherwise false.
|
||||
*
|
||||
* \see Ipv4StaticRouting
|
||||
* \see Ipv4RoutingProtocol
|
||||
* \see Ipv4L3Protocol
|
||||
*/
|
||||
virtual bool RequestIfIndex (Ipv4Address destination,
|
||||
uint32_t& ifIndex) = 0;
|
||||
|
||||
static const uint32_t IF_INDEX_ANY = 0xffffffff;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -194,16 +233,68 @@ public:
|
||||
* \returns the number of entries in the routing table.
|
||||
*/
|
||||
virtual uint32_t GetNRoutes (void) = 0;
|
||||
|
||||
/**
|
||||
* \param i index of route to return
|
||||
* \returns the route whose index is i
|
||||
*/
|
||||
virtual Ipv4Route GetRoute (uint32_t i) = 0;
|
||||
|
||||
/**
|
||||
* \param i index of route to remove from routing table.
|
||||
*/
|
||||
virtual void RemoveRoute (uint32_t i) = 0;
|
||||
|
||||
/**
|
||||
* \brief Add a static multicast route for a given multicast source and
|
||||
* group.
|
||||
*
|
||||
* \param origin The Ipv4 address of the multicast source.
|
||||
* \param group The multicast group address.
|
||||
* \param inputInterface The interface index over which the packet arrived.
|
||||
* \param outputInterfaces The list of output interface indices over which
|
||||
* the packet should be sent (excluding the inputInterface).
|
||||
*/
|
||||
virtual void AddMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface,
|
||||
std::vector<uint32_t> outputInterfaces) = 0;
|
||||
/**
|
||||
* \brief Remove a static multicast route for a given multicast source and
|
||||
* group.
|
||||
*
|
||||
* \param origin The Ipv4 address of the multicast source.
|
||||
* \param group The multicast group address.
|
||||
* \param inputInterface The interface index over which the packet arrived.
|
||||
*/
|
||||
virtual void RemoveMulticastRoute (Ipv4Address origin,
|
||||
Ipv4Address group,
|
||||
uint32_t inputInterface) = 0;
|
||||
|
||||
/**
|
||||
* \brief Set the default static multicast route.
|
||||
*
|
||||
* \param outputInterface The network output interface index over which
|
||||
* packets without specific routes should be sent.
|
||||
*/
|
||||
virtual void SetDefaultMulticastRoute (uint32_t outputInterface) = 0;
|
||||
|
||||
/**
|
||||
* \returns the number of entries in the multicast routing table.
|
||||
*/
|
||||
virtual uint32_t GetNMulticastRoutes (void) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of route to return
|
||||
* \returns the route whose index is i
|
||||
*/
|
||||
virtual Ipv4MulticastRoute GetMulticastRoute (uint32_t i) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of route to remove from routing table.
|
||||
*/
|
||||
virtual void RemoveMulticastRoute (uint32_t i) = 0;
|
||||
|
||||
/**
|
||||
* \param device device to add to the list of ipv4 interfaces
|
||||
* which can be used as output interfaces during packet forwarding.
|
||||
@@ -214,49 +305,120 @@ public:
|
||||
* make sure that it is never used during packet forwarding.
|
||||
*/
|
||||
virtual uint32_t AddInterface (Ptr<NetDevice> device) = 0;
|
||||
|
||||
/**
|
||||
* \returns the number of interfaces added by the user.
|
||||
*/
|
||||
virtual uint32_t GetNInterfaces (void) = 0;
|
||||
|
||||
/**
|
||||
* \brief Find and return the interface ID of the interface that has been
|
||||
* assigned the specified IP address.
|
||||
* \param addr The IP address assigned to the interface of interest.
|
||||
* \returns The index of the ipv4 interface with the given address.
|
||||
*
|
||||
* Each IP interface has an IP address associated with it. It is often
|
||||
* useful to search the list of interfaces for one that corresponds to
|
||||
* a known IP Address. This call takes an IP address as a parameter and
|
||||
* returns the interface index of the first interface that has been assigned
|
||||
* that address. If the address is not found, this function asserts.
|
||||
*/
|
||||
virtual uint32_t FindInterfaceForAddr (Ipv4Address addr) const = 0;
|
||||
|
||||
/**
|
||||
* \brief Find and return the interface ID of the interface that has been
|
||||
* assigned the specified (masked) IP address.
|
||||
* \param addr The IP address assigned to the interface of interest.
|
||||
* \param mask The address mask to be used in address matching.
|
||||
* \returns The index of the ipv4 interface with the given address.
|
||||
*
|
||||
* Each IP interface has an IP address associated with it. It is often
|
||||
* useful to search the list of interfaces for one that corresponds to
|
||||
* a known IP Address. This call takes an IP address and an IP address
|
||||
* mask as parameters and returns the interface index of the first interface
|
||||
* that matches the masked IP address.
|
||||
*/
|
||||
virtual uint32_t FindInterfaceForAddr (Ipv4Address addr,
|
||||
Ipv4Mask mask) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \returns the NetDevice associated with the ipv4 interface index
|
||||
*/
|
||||
virtual Ptr<NetDevice> GetNetDevice (uint32_t i) = 0;
|
||||
|
||||
/**
|
||||
* \brief Join a multicast group for a given multicast source and
|
||||
* group.
|
||||
*
|
||||
* \param origin The Ipv4 address of the multicast source.
|
||||
* \param group The multicast group address.
|
||||
*/
|
||||
virtual void JoinMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0;
|
||||
|
||||
/**
|
||||
* \brief Leave a multicast group for a given multicast source and
|
||||
* group.
|
||||
*
|
||||
* \param origin The Ipv4 address of the multicast source.
|
||||
* \param group The multicast group address.
|
||||
*/
|
||||
virtual void LeaveMulticastGroup (Ipv4Address origin, Ipv4Address group) = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \param address address to associate to the underlying ipv4 interface
|
||||
*/
|
||||
virtual void SetAddress (uint32_t i, Ipv4Address address) = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \param mask mask to associate to the underlying ipv4 interface
|
||||
*/
|
||||
virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask) = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \returns the mask associated to the underlying ipv4 interface
|
||||
*/
|
||||
virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \returns the address associated to the underlying ipv4 interface
|
||||
*/
|
||||
virtual Ipv4Address GetAddress (uint32_t i) const = 0;
|
||||
|
||||
/**
|
||||
* \param destination The IP address of a hypothetical destination.
|
||||
* \returns The IP address assigned to the interface that will be used
|
||||
* if we were to send a packet to destination.
|
||||
*/
|
||||
virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const = 0;
|
||||
|
||||
/**
|
||||
* \param destination The IP address of a hypothetical destination.
|
||||
* \param ifIndex filled in with the interface index that will be used to
|
||||
* send a packet to the hypothetical destination.
|
||||
* \returns True if a single interface can be identified, false otherwise.
|
||||
*/
|
||||
virtual bool GetIfIndexForDestination (Ipv4Address dest,
|
||||
uint32_t &ifIndex) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \returns the Maximum Transmission Unit (in bytes) associated
|
||||
* to the underlying ipv4 interface
|
||||
*/
|
||||
virtual uint16_t GetMtu (uint32_t i) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \returns true if the underlying interface is in the "up" state,
|
||||
* false otherwise.
|
||||
*/
|
||||
virtual bool IsUp (uint32_t i) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
*
|
||||
@@ -264,6 +426,7 @@ public:
|
||||
* considered valid during ipv4 forwarding.
|
||||
*/
|
||||
virtual void SetUp (uint32_t i) = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
*
|
||||
@@ -271,21 +434,18 @@ public:
|
||||
* ignored during ipv4 forwarding.
|
||||
*/
|
||||
virtual void SetDown (uint32_t i) = 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience functions (Doxygen still needed)
|
||||
*
|
||||
* Return the ifIndex corresponding to the Ipv4Address provided.
|
||||
*/
|
||||
uint32_t GetIfIndexByIpv4Address (Ptr<Node> node,
|
||||
Ipv4Address a,
|
||||
Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
|
||||
static uint32_t GetIfIndexByAddress (Ptr<Node> node, Ipv4Address a,
|
||||
Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
|
||||
|
||||
bool GetIpv4RouteToDestination (Ptr<Node> node, Ipv4Route& route,
|
||||
Ipv4Address a,
|
||||
Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
|
||||
static bool GetRouteToDestination (Ptr<Node> node, Ipv4Route& route,
|
||||
Ipv4Address a, Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ NetDevice::IsBroadcast (void) const
|
||||
{
|
||||
return m_isBroadcast;
|
||||
}
|
||||
|
||||
Address const &
|
||||
NetDevice::GetBroadcast (void) const
|
||||
{
|
||||
@@ -140,10 +141,27 @@ NetDevice::IsMulticast (void) const
|
||||
return m_isMulticast;
|
||||
}
|
||||
|
||||
Address
|
||||
NetDevice::GetMulticast (void) const
|
||||
{
|
||||
NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): "
|
||||
"Invalid operation when not IsMulticast ()");
|
||||
return m_multicast;
|
||||
}
|
||||
|
||||
Address
|
||||
NetDevice::MakeMulticastAddress(Ipv4Address multicastGroup) const
|
||||
{
|
||||
NS_ASSERT_MSG (m_isMulticast, "NetDevice::GetMulticast (): "
|
||||
"Invalid operation when not IsMulticast ()");
|
||||
return m_multicast;
|
||||
}
|
||||
|
||||
void
|
||||
NetDevice::EnableMulticast (void)
|
||||
NetDevice::EnableMulticast (Address multicast)
|
||||
{
|
||||
m_isMulticast = true;
|
||||
m_multicast = multicast;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "address.h"
|
||||
#include "ipv4-address.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -130,10 +131,69 @@ public:
|
||||
* not true.
|
||||
*/
|
||||
Address const &GetBroadcast (void) const;
|
||||
|
||||
/**
|
||||
* \return value of m_isMulticast flag
|
||||
*/
|
||||
bool IsMulticast (void) const;
|
||||
|
||||
/**
|
||||
* \brief Return the MAC multicast base address used when mapping multicast
|
||||
* groups to MAC multicast addresses.
|
||||
*
|
||||
* Typically when one constructs a multicast MAC addresses, some bits from
|
||||
* the IP multicast group are copied into a corresponding MAC multicast
|
||||
* group. In EUI-48, for example, the low order 23 bits of the multicast
|
||||
* group are copied to the MAC multicast group base address.
|
||||
*
|
||||
* This method allows access to the underlying MAC multicast group base
|
||||
* address. It is expected that in most cases, a net device client will
|
||||
* allow the net device to perform the actual construction of the multicast
|
||||
* address. Use of this method is discouraged unless you have a good reason
|
||||
* to perform a custom mapping. You should prefer
|
||||
* NetDevice::MakeMulticastAddress which will do the RFC-specified mapping
|
||||
* for the net device in question.
|
||||
*
|
||||
* \return The multicast address supported by this net device.
|
||||
*
|
||||
* \warning Calling this method is invalid if IsMulticast returns not true.
|
||||
* The method NS_ASSERTs if the device is not a multicast device.
|
||||
* \see NetDevice::MakeMulticastAddress
|
||||
*/
|
||||
Address GetMulticast (void) const;
|
||||
|
||||
/**
|
||||
* \brief Make and return a MAC multicast address using the provided
|
||||
* multicast group
|
||||
*
|
||||
* RFC 1112 says that an Ipv4 host group address is mapped to an Ethernet
|
||||
* multicast address by placing the low-order 23-bits of the IP address into
|
||||
* the low-order 23 bits of the Ethernet multicast address
|
||||
* 01-00-5E-00-00-00 (hex). Similar RFCs exist for Ipv6 and Eui64 mappings.
|
||||
* This method performs the multicast address creation function appropriate
|
||||
* to the underlying MAC address of the device. This MAC address is
|
||||
* encapsulated in an abstract Address to avoid dependencies on the exact
|
||||
* MAC address format.
|
||||
*
|
||||
* A default imlementation of MakeMulticastAddress is provided, but this
|
||||
* method simply NS_ASSERTS. In the case of net devices that do not support
|
||||
* multicast, clients are expected to test NetDevice::IsMulticast and avoid
|
||||
* attempting to map multicast packets. Subclasses of NetDevice that do
|
||||
* support multicasting are expected to override this method and provide an
|
||||
* implementation appropriate to the particular device.
|
||||
*
|
||||
* \param multicastGroup The IP address for the multicast group destination
|
||||
* of the packet.
|
||||
* \return The MAC multicast Address used to send packets to the provided
|
||||
* multicast group.
|
||||
*
|
||||
* \warning Calling this method is invalid if IsMulticast returns not true.
|
||||
* \see Ipv4Address
|
||||
* \see Address
|
||||
* \see NetDevice::IsMulticast
|
||||
*/
|
||||
virtual Address MakeMulticastAddress (Ipv4Address multicastGroup) const;
|
||||
|
||||
/**
|
||||
* \return value of m_isPointToPoint flag
|
||||
*/
|
||||
@@ -204,9 +264,10 @@ public:
|
||||
*/
|
||||
void DisableBroadcast (void);
|
||||
/**
|
||||
* Set m_isMulticast flag to true
|
||||
* Enable multicast support. This method should be
|
||||
* called by subclasses from their constructor
|
||||
*/
|
||||
void EnableMulticast (void);
|
||||
void EnableMulticast (Address multicast);
|
||||
/**
|
||||
* Set m_isMulticast flag to false
|
||||
*/
|
||||
@@ -286,6 +347,7 @@ public:
|
||||
uint16_t m_ifIndex;
|
||||
Address m_address;
|
||||
Address m_broadcast;
|
||||
Address m_multicast;
|
||||
uint16_t m_mtu;
|
||||
bool m_isUp;
|
||||
bool m_isBroadcast;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +14,8 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
*/
|
||||
|
||||
#include "ns3/debug.h"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +14,8 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
*/
|
||||
|
||||
#ifndef CANDIDATE_QUEUE_H
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
* Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +15,12 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
* Tom Henderson (tomhend@u.washington.edu)
|
||||
*
|
||||
* Kunihiro Ishigura, Toshiaki Takada (GNU Zebra) are attributed authors
|
||||
* of the quagga 0.99.7/src/ospfd/ospf_spf.c code which was ported here
|
||||
*/
|
||||
|
||||
#include <utility>
|
||||
@@ -1143,7 +1152,7 @@ GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
|
||||
// we're looking for. If we find one, return the corresponding interface
|
||||
// index.
|
||||
//
|
||||
return (GetIfIndexByIpv4Address (node, a, amask) );
|
||||
return (Ipv4::GetIfIndexByAddress (node, a, amask) );
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +14,9 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
* Tom Henderson (tomhend@u.washington.edu)
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_ROUTE_MANAGER_IMPL_H
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +14,9 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
* Tom Henderson (tomhend@u.washington.edu)
|
||||
*/
|
||||
|
||||
#include "ns3/assert.h"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +14,9 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
* Tom Henderson (tomhend@u.washington.edu)
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_ROUTE_MANAGER_H
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +14,9 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
* Tom Henderson (tomhend@u.washington.edu)
|
||||
*/
|
||||
|
||||
#include "ns3/debug.h"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright 2007 University of Washington
|
||||
*
|
||||
* 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;
|
||||
@@ -12,6 +14,9 @@
|
||||
* 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: Craig Dowell (craigdo@ee.washington.edu)
|
||||
* Tom Henderson (tomhend@u.washington.edu)
|
||||
*/
|
||||
|
||||
#ifndef GLOBAL_ROUTER_INTERFACE_H
|
||||
|
||||
Reference in New Issue
Block a user