merge with HEAD
This commit is contained in:
1
.hgtags
1
.hgtags
@@ -6,3 +6,4 @@
|
||||
08046b6aef37932507696a2f2f427b42d693781e release ns-3.0.5
|
||||
267e2ebc28e4e4ae2f579e1cfc29902acade0c34 buffer-working-before-breaking
|
||||
606df29888e7573b825fc891a002f0757166b616 release ns-3.0.6
|
||||
36472385a1cc7c44d34fb7a5951b930010f4e8d2 release ns-3.0.7
|
||||
|
||||
10
README
10
README
@@ -84,12 +84,12 @@ following set of platforms:
|
||||
- linux x86 gcc 4.2, 4.1, and, 3.4.
|
||||
- linux x86_64 gcc 4.0
|
||||
- MacOS X ppc and x86
|
||||
- cygwin
|
||||
|
||||
The current codebase is expected to fail to build on
|
||||
the following platforms:
|
||||
- gcc 3.3 and earlier
|
||||
- optimized builds on linux x86 gcc 4.0
|
||||
- cygwin
|
||||
|
||||
Other platforms may or may not work: we welcome
|
||||
patches to improve the portability of the code to these
|
||||
@@ -102,17 +102,17 @@ On recent Linux systems, once you have built ns-3, it
|
||||
should be easy to run the sample programs with the
|
||||
following command:
|
||||
|
||||
./waf --run simple-p2p
|
||||
./waf --run simple-point-to-point
|
||||
|
||||
That program should generate a simple-p2p.tr text
|
||||
trace file and a set of simple-p2p-xx-xx.pcap binary
|
||||
That program should generate a simple-point-to-point.tr text
|
||||
trace file and a set of simple-point-to-point-xx-xx.pcap binary
|
||||
pcap trace files, which can be read by tcpdump.
|
||||
|
||||
5) Getting access to the ns-3 documentation
|
||||
-------------------------------------------
|
||||
|
||||
Once you have verified that your build of ns-3 works by running
|
||||
the simple-p2p example as outlined in 4) above, it is
|
||||
the simple-point-to-point example as outlined in 4) above, it is
|
||||
quite likely that you will want to get started on reading
|
||||
some ns-3 documentation.
|
||||
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
|
||||
This file contains ns-3 release notes (most recent releases first).
|
||||
|
||||
Release 3.0.7 (2007/10/15)
|
||||
========================
|
||||
- OLSR routing protocol
|
||||
- A timer class
|
||||
- Additional mobility models (random waypoint, random 2D walk)
|
||||
- A mobility visualization tool
|
||||
|
||||
Release 3.0.6 (2007/09/15)
|
||||
========================
|
||||
- Static multicast IPv4 routing
|
||||
|
||||
@@ -3,79 +3,62 @@ build system (http://www.freehackers.org/~tnagy/waf.html)
|
||||
|
||||
=== Installing Waf ===
|
||||
|
||||
If this file is part of a development release tarball, the top-level
|
||||
ns-3 directory should contain a current waf script.
|
||||
|
||||
However, the ns-3 Mercurial code repository does not contain the waf
|
||||
script. Instead, developers should check it out from a subversion
|
||||
repository:
|
||||
|
||||
svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf
|
||||
|
||||
[ note: 'tags/ns3' is a tag that represents the last svn version
|
||||
tested to work correctly with ns3, although 'trunk' will likely work
|
||||
as well ]
|
||||
|
||||
Then it can be installed system-wide with 'sudo waf-light install'.
|
||||
When preparing a distribution, the resulting 'waf' script, which is
|
||||
self contained (no external files needed), can be easily included in
|
||||
the tarball so that users downloading ns-3 can easily build it without
|
||||
having Waf installed (although Python >= 2.3 is still needed).
|
||||
The top-level ns-3 directory should contain a current waf script.
|
||||
|
||||
=== Building with Waf ===
|
||||
|
||||
To build ns-3 with waf type the commands:
|
||||
1. waf configure [options]
|
||||
2. waf
|
||||
To build ns-3 with waf type the commands from the top-level directory:
|
||||
1. ./waf configure [options]
|
||||
2. ./waf
|
||||
|
||||
To see valid configure options, type waf --help. The most important
|
||||
To see valid configure options, type ./waf --help. The most important
|
||||
option is -d <debug level>. Valid debug levels (which are listed in
|
||||
waf --help) are: ultradebug, debug, release, and optimized. It is
|
||||
waf --help) are: "debug" or "optimized". It is
|
||||
also possible to change the flags used for compilation with (e.g.):
|
||||
CXXFLAGS="-O3" waf configure.
|
||||
CXXFLAGS="-O3" ./waf configure.
|
||||
|
||||
[ Note: Unlike some other build tools, to change the build target,
|
||||
the option must be supplied during the configure stage rather than
|
||||
the build stage (i.e., "waf -d optimized" will not work; instead, do
|
||||
"waf -d optimized configure; waf" ]
|
||||
the build stage (i.e., "./waf -d optimized" will not work; instead, do
|
||||
"./waf -d optimized configure; ./waf" ]
|
||||
|
||||
The resulting binaries are placed in build/<debuglevel>/srcpath.
|
||||
|
||||
Other waf usages include:
|
||||
|
||||
1. waf check
|
||||
1. ./waf check
|
||||
Runs the unit tests
|
||||
|
||||
2. waf --doxygen
|
||||
2. ./waf --doxygen
|
||||
Run doxygen to generate documentation
|
||||
|
||||
3. waf --lcov-report
|
||||
3. ./waf --lcov-report
|
||||
Run code coverage analysis (assuming the project was configured
|
||||
with --enable-gcov)
|
||||
|
||||
4. waf --run "program [args]"
|
||||
4. ./waf --run "program [args]"
|
||||
Run a ns3 program, given its target name, with the given
|
||||
arguments. This takes care of automatically modifying the the
|
||||
path for finding the ns3 dynamic libraries in the environment
|
||||
before running the program. Note: the "program [args]" string is
|
||||
parsed using POSIX shell rules.
|
||||
|
||||
4.1 waf --run programname --command-template "... %s ..."
|
||||
4.1 ./waf --run programname --command-template "... %s ..."
|
||||
|
||||
Same as --run, but uses a command template with %s replaced by the
|
||||
actual program (whose name is given by --run). This can be use to
|
||||
run ns-3 programs with helper tools. For example, to run unit
|
||||
tests with valgrind, use the command:
|
||||
|
||||
waf --run run-tests --command-template "valgrind %s"
|
||||
./waf --run run-tests --command-template "valgrind %s"
|
||||
|
||||
5. waf --shell
|
||||
5. ./waf --shell
|
||||
Starts a nested system shell with modified environment to run ns3 programs.
|
||||
|
||||
6. waf distclean
|
||||
6. ./waf distclean
|
||||
Cleans out the entire build/ directory
|
||||
|
||||
7. waf dist
|
||||
7. ./waf dist
|
||||
The command 'waf dist' can be used to create a distribution tarball.
|
||||
It includes all files in the source directory, except some particular
|
||||
extensions that are blacklisted, such as back files (ending in ~).
|
||||
|
||||
@@ -472,6 +472,9 @@ RECURSIVE = YES
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
|
||||
EXCLUDE = \
|
||||
src/routing/olsr/olsr-state.h \
|
||||
src/routing/olsr/repositories.h \
|
||||
src/routing/olsr/routing-table.h \
|
||||
src/simulator/high-precision.h \
|
||||
src/simulator/high-precision-128.h \
|
||||
src/simulator/high-precision-double.h
|
||||
|
||||
@@ -65,4 +65,4 @@
|
||||
/**
|
||||
* \defgroup constants Constants
|
||||
* \brief Constants you can change
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -1,24 +1,32 @@
|
||||
Steps in doing an ns-3 release
|
||||
|
||||
0. check out a clean ns-3-dev somewhere
|
||||
1. prepare the source files
|
||||
- revise and check in AUTHORS, if needed
|
||||
- revise and check in RELEASE_NOTES
|
||||
- update and check in VERSION to the latest release number
|
||||
2. make a new "architecture.pdf" document and place it in the doc/ directory
|
||||
3. cd ns-3-dev; ./waf configure; ./waf dist
|
||||
of the ns-3-dev working directory
|
||||
3. ./waf configure; ./waf dist
|
||||
- this will create a ns-3.0.x.tar.bz2 tarball
|
||||
4. test tarball on release platforms (waf check and maybe some other scripts)
|
||||
5. tag ns-3-dev with "release ns-3.0.X"
|
||||
- hg tag "release ns-3.0.x"
|
||||
- hg push
|
||||
5. once you are happy with the tarball, tag ns-3-dev with "release ns-3.0.X"
|
||||
- hg tag "release ns-3.0.x"
|
||||
- hg push
|
||||
6. clone the tagged ns-3-dev and place it on the repository
|
||||
- ssh code.nsnam.org; sudo; su code;
|
||||
- cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x
|
||||
- cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately
|
||||
7. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server
|
||||
- ssh code.nsnam.org; sudo; su code;
|
||||
- cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x
|
||||
- cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately
|
||||
7. upload "ns-3.0.x.tar.bz2" to the /var/www/html/releases/ directory on
|
||||
the www.nsnam.org server
|
||||
8. update web page
|
||||
- add link to news.html
|
||||
- update download.html
|
||||
- update roadmap.html
|
||||
- update getting_started.html
|
||||
- update documents.html
|
||||
- update roadmap on wiki
|
||||
- build and update Doxygen directory on the server
|
||||
-- ssh www.nsnam.org; sudo tcsh; su nsnam;
|
||||
-- ~/bin/update-doxygen-release
|
||||
- update and upload software architecture document (PDF, HTML)
|
||||
-- note: HTML image generation is not currently automatic
|
||||
9. announce to ns-developers, with summary of release notes
|
||||
|
||||
224
examples/simple-alternate-routing.cc
Normal file
224
examples/simple-alternate-routing.cc
Normal file
@@ -0,0 +1,224 @@
|
||||
/* -*- 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
|
||||
//
|
||||
// n0
|
||||
// \ 5 Mb/s, 2ms
|
||||
// \ 1.5Mb/s, 10ms
|
||||
// n2 ------------------------n3
|
||||
// / /
|
||||
// / 5 Mb/s, 2ms /
|
||||
// n1--------------------------
|
||||
// 1.5 Mb/s, 100ms
|
||||
//
|
||||
// this is a modification of simple-global-routing to allow for
|
||||
// a single hop but higher-cost path between n1 and n3
|
||||
//
|
||||
// - Tracing of queues and packet receptions to file "simple-rerouting.tr"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#include "ns3/log.h"
|
||||
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/default-value.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/random-variable.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/point-to-point-channel.h"
|
||||
#include "ns3/point-to-point-net-device.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/ipv4.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/inet-socket-address.h"
|
||||
#include "ns3/ipv4-route.h"
|
||||
#include "ns3/point-to-point-topology.h"
|
||||
#include "ns3/onoff-application.h"
|
||||
#include "ns3/packet-sink.h"
|
||||
#include "ns3/global-route-manager.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("SimpleAlternateRoutingExample");
|
||||
|
||||
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
|
||||
LogComponentEnable("GlobalRouteManager", LOG_LOGIC);
|
||||
LogComponentEnable("GlobalRouter", LOG_LOGIC);
|
||||
LogComponentEnable("Object", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Queue", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Channel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("NetDevice", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("PacketSocket", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Socket", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpSocket", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL);
|
||||
#endif
|
||||
// Set up some default values for the simulation. Use the
|
||||
// DefaultValue::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
|
||||
DefaultValue::Bind ("Queue", "DropTailQueue");
|
||||
|
||||
DefaultValue::Bind ("OnOffApplicationPacketSize", "210");
|
||||
DefaultValue::Bind ("OnOffApplicationDataRate", "300b/s");
|
||||
|
||||
// The below metric, if set to 3 or higher, will cause packets between
|
||||
// n1 and n3 to take the 2-hop route through n2
|
||||
//
|
||||
// Additionally, we plumb this metric into the default value / command
|
||||
// line argument system as well, for exemplary purposes. This means
|
||||
// that it can be resettable at the command-line to the program,
|
||||
// rather than recompiling
|
||||
// e.g. waf --run "simple-alternate-routing --AlternateCost=5"
|
||||
uint16_t sampleMetric = 1;
|
||||
CommandLine::AddArgValue ("AlternateCost",
|
||||
"This metric is used in the example script between n3 and n1 ",
|
||||
sampleMetric);
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// DefaultValue::Bind ()s at run-time, via command-line arguments
|
||||
CommandLine::Parse (argc, argv);
|
||||
|
||||
// Here, we will explicitly create four nodes. In more sophisticated
|
||||
// topologies, we could configure a node factory.
|
||||
NS_LOG_INFO ("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_LOG_INFO ("Create channels.");
|
||||
Ptr<PointToPointChannel> channel0 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n0, n2, DataRate (5000000), MilliSeconds (2));
|
||||
|
||||
Ptr<PointToPointChannel> channel1 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n1, n2, DataRate (5000000), MilliSeconds (2));
|
||||
|
||||
Ptr<PointToPointChannel> channel2 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n2, n3, DataRate (1500000), MilliSeconds (10));
|
||||
|
||||
Ptr<PointToPointChannel> channel3 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n1, n3, DataRate (1500000), MilliSeconds (100));
|
||||
|
||||
// Later, we add IP addresses. The middle two octets correspond to
|
||||
// the channel number.
|
||||
NS_LOG_INFO ("Assign IP Addresses.");
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel0, n0, Ipv4Address ("10.0.0.1"),
|
||||
n2, Ipv4Address ("10.0.0.2"));
|
||||
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel1, n1, Ipv4Address ("10.1.1.1"),
|
||||
n2, Ipv4Address ("10.1.1.2"));
|
||||
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel2, n2, Ipv4Address ("10.2.2.1"),
|
||||
n3, Ipv4Address ("10.2.2.2"));
|
||||
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel3, n1, Ipv4Address ("10.3.3.1"),
|
||||
n3, Ipv4Address ("10.3.3.2"));
|
||||
|
||||
PointToPointTopology::SetIpv4Metric (
|
||||
channel3, n1, n3, sampleMetric);
|
||||
|
||||
// Create router nodes, initialize routing database and set up the routing
|
||||
// tables in the nodes.
|
||||
GlobalRouteManager::PopulateRoutingTables ();
|
||||
|
||||
// Create the OnOff application to send UDP datagrams
|
||||
NS_LOG_INFO ("Create Application.");
|
||||
uint16_t port = 9; // Discard port (RFC 863)
|
||||
|
||||
// Create a flow from n3 to n1, starting at time 1.1 seconds
|
||||
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
|
||||
n3,
|
||||
InetSocketAddress ("10.1.1.1", port),
|
||||
"Udp",
|
||||
ConstantVariable (1),
|
||||
ConstantVariable (0));
|
||||
// Start the application
|
||||
ooff->Start (Seconds (1.1));
|
||||
ooff->Stop (Seconds (10.0));
|
||||
|
||||
// Create a packet sink to receive these packets
|
||||
Ptr<PacketSink> sink = Create<PacketSink> (
|
||||
n1,
|
||||
InetSocketAddress (Ipv4Address::GetAny (), port),
|
||||
"Udp");
|
||||
// Start the sink
|
||||
sink->Start (Seconds (1.1));
|
||||
sink->Stop (Seconds (10.0));
|
||||
|
||||
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
|
||||
// Trace output will be sent to the simple-alternate-routing.tr file
|
||||
NS_LOG_INFO ("Configure Tracing.");
|
||||
AsciiTrace asciitrace ("simple-alternate-routing.tr");
|
||||
asciitrace.TraceAllQueues ();
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
|
||||
// Also configure some tcpdump traces; each interface will be traced
|
||||
// The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
|
||||
// and can be read by the "tcpdump -r" command (use "-tt" option to
|
||||
// display timestamps correctly)
|
||||
PcapTrace pcaptrace ("simple-alternate-routing.pcap");
|
||||
pcaptrace.TraceAllIp ();
|
||||
|
||||
NS_LOG_INFO ("Run Simulation.");
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
NS_LOG_INFO ("Done.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
233
examples/simple-point-to-point-olsr.cc
Normal file
233
examples/simple-point-to-point-olsr.cc
Normal file
@@ -0,0 +1,233 @@
|
||||
/* -*- 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
|
||||
*
|
||||
* ns-2 simple.tcl script (ported from ns-2)
|
||||
* Originally authored by Steve McCanne, 12/19/1996
|
||||
*/
|
||||
|
||||
// Port of ns-2/tcl/ex/simple.tcl to ns-3
|
||||
//
|
||||
// Network topology
|
||||
//
|
||||
// n0
|
||||
// \ 5 Mb/s, 2ms
|
||||
// \ 1.5Mb/s, 10ms
|
||||
// n2 -------------------------n3
|
||||
// /
|
||||
// / 5 Mb/s, 2ms
|
||||
// n1
|
||||
//
|
||||
// - all links are point-to-point links with indicated one-way BW/delay
|
||||
// - CBR/UDP flows from n0 to n3, and from n3 to n1
|
||||
// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec.
|
||||
// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
|
||||
// (i.e., DataRate of 448,000 bps)
|
||||
// - DropTail queues
|
||||
// - Tracing of queues and packet receptions to file
|
||||
// "simple-point-to-point.tr"
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/default-value.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/random-variable.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/point-to-point-channel.h"
|
||||
#include "ns3/point-to-point-net-device.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/point-to-point-topology.h"
|
||||
#include "ns3/onoff-application.h"
|
||||
#include "ns3/packet-sink.h"
|
||||
#include "ns3/olsr.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("SimplePointToPointExample");
|
||||
|
||||
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
|
||||
LogComponentEnable ("SimplePointToPointExample", LOG_LEVEL_INFO);
|
||||
|
||||
LogComponentEnable("Object", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Queue", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Channel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("NetDevice", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("PacketSocket", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Socket", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpSocket", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpL4Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4StaticRouting", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("ArpIpv4Interface", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("Ipv4LoopbackInterface", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("OnOffApplication", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("PacketSinkApplication", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_ALL);
|
||||
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_ALL);
|
||||
#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
|
||||
DefaultValue::Bind ("Queue", "DropTailQueue");
|
||||
|
||||
DefaultValue::Bind ("OnOffApplicationPacketSize", "210");
|
||||
DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s");
|
||||
|
||||
//DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);
|
||||
|
||||
// Allow the user to override any of the defaults and the above
|
||||
// Bind()s at run-time, via command-line arguments
|
||||
CommandLine::Parse (argc, argv);
|
||||
|
||||
// Here, we will explicitly create four nodes. In more sophisticated
|
||||
// topologies, we could configure a node factory.
|
||||
NS_LOG_INFO ("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_LOG_INFO ("Create channels.");
|
||||
Ptr<PointToPointChannel> channel0 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n0, n2, DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
Ptr<PointToPointChannel> channel1 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n1, n2, DataRate(5000000), MilliSeconds(2));
|
||||
|
||||
Ptr<PointToPointChannel> channel2 =
|
||||
PointToPointTopology::AddPointToPointLink (
|
||||
n2, n3, DataRate(1500000), MilliSeconds(10));
|
||||
|
||||
// Later, we add IP addresses.
|
||||
NS_LOG_INFO ("Assign IP Addresses.");
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel0, n0, Ipv4Address("10.1.1.1"),
|
||||
n2, Ipv4Address("10.1.1.2"));
|
||||
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel1, n1, Ipv4Address("10.1.2.1"),
|
||||
n2, Ipv4Address("10.1.2.2"));
|
||||
|
||||
PointToPointTopology::AddIpv4Addresses (
|
||||
channel2, n2, Ipv4Address("10.1.3.1"),
|
||||
n3, Ipv4Address("10.1.3.2"));
|
||||
|
||||
// Finally, we add static routes. These three steps (Channel and
|
||||
// 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_LOG_INFO ("Enabling OLSR Routing.");
|
||||
olsr::EnableAllNodes ();
|
||||
|
||||
// Create the OnOff application to send UDP datagrams of size
|
||||
// 210 bytes at a rate of 448 Kb/s
|
||||
NS_LOG_INFO ("Create Applications.");
|
||||
uint16_t port = 9; // Discard port (RFC 863)
|
||||
Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
|
||||
n0,
|
||||
InetSocketAddress ("10.1.3.2", port),
|
||||
"Udp",
|
||||
ConstantVariable(1),
|
||||
ConstantVariable(0));
|
||||
// Start the application
|
||||
ooff->Start(Seconds(1.0));
|
||||
ooff->Stop (Seconds(10.0));
|
||||
|
||||
// Create an optional packet sink to receive these packets
|
||||
Ptr<PacketSink> sink = Create<PacketSink> (
|
||||
n3,
|
||||
InetSocketAddress (Ipv4Address::GetAny (), port),
|
||||
"Udp");
|
||||
// Start the sink
|
||||
sink->Start (Seconds (1.0));
|
||||
sink->Stop (Seconds (10.0));
|
||||
|
||||
// Create a similar flow from n3 to n1, starting at time 1.1 seconds
|
||||
ooff = Create<OnOffApplication> (
|
||||
n3,
|
||||
InetSocketAddress ("10.1.2.1", port),
|
||||
"Udp",
|
||||
ConstantVariable(1),
|
||||
ConstantVariable(0));
|
||||
// Start the application
|
||||
ooff->Start(Seconds(1.1));
|
||||
ooff->Stop (Seconds(10.0));
|
||||
|
||||
// Create a packet sink to receive these packets
|
||||
sink = Create<PacketSink> (
|
||||
n1,
|
||||
InetSocketAddress (Ipv4Address::GetAny (), port),
|
||||
"Udp");
|
||||
// Start the sink
|
||||
sink->Start (Seconds (1.1));
|
||||
sink->Stop (Seconds (10.0));
|
||||
|
||||
// Here, finish off packet routing configuration
|
||||
// This will likely set by some global StaticRouting object in the future
|
||||
NS_LOG_INFO ("Set Default Routes.");
|
||||
Ptr<Ipv4> ipv4;
|
||||
ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
|
||||
ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
|
||||
|
||||
// Configure tracing of all enqueue, dequeue, and NetDevice receive events
|
||||
// Trace output will be sent to the simple-point-to-point.tr file
|
||||
NS_LOG_INFO ("Configure Tracing.");
|
||||
AsciiTrace asciitrace ("simple-point-to-point-olsr.tr");
|
||||
asciitrace.TraceAllQueues ();
|
||||
asciitrace.TraceAllNetDeviceRx ();
|
||||
|
||||
// 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)
|
||||
PcapTrace pcaptrace ("simple-point-to-point-olsr.pcap");
|
||||
pcaptrace.TraceAllIp ();
|
||||
|
||||
NS_LOG_INFO ("Run Simulation.");
|
||||
Simulator::StopAt (Seconds (10));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
NS_LOG_INFO ("Done.");
|
||||
}
|
||||
@@ -227,6 +227,7 @@ main (int argc, char *argv[])
|
||||
pcaptrace.TraceAllIp ();
|
||||
|
||||
NS_LOG_INFO ("Run Simulation.");
|
||||
Simulator::StopAt (Seconds (10));
|
||||
Simulator::Run ();
|
||||
Simulator::Destroy ();
|
||||
NS_LOG_INFO ("Done.");
|
||||
|
||||
@@ -6,6 +6,10 @@ def build(bld):
|
||||
['point-to-point', 'internet-node', 'global-routing'])
|
||||
obj.source = 'simple-global-routing.cc'
|
||||
|
||||
obj = bld.create_ns3_program('simple-alternate-routing',
|
||||
['point-to-point', 'internet-node', 'global-routing'])
|
||||
obj.source = 'simple-alternate-routing.cc'
|
||||
|
||||
obj = bld.create_ns3_program('simple-point-to-point',
|
||||
['point-to-point', 'internet-node'])
|
||||
obj.source = 'simple-point-to-point.cc'
|
||||
@@ -33,3 +37,7 @@ def build(bld):
|
||||
obj = bld.create_ns3_program( 'mixed-global-routing',
|
||||
['point-to-point', 'internet-node', 'global-routing' , 'csma-cd'])
|
||||
obj.source = 'mixed-global-routing.cc'
|
||||
|
||||
obj = bld.create_ns3_program('simple-point-to-point-olsr',
|
||||
['point-to-point', 'internet-node', 'olsr'])
|
||||
obj.source = 'simple-point-to-point-olsr.cc'
|
||||
|
||||
@@ -244,6 +244,16 @@ public:
|
||||
* A packet is allocated a new uid when it is created
|
||||
* empty or with zero-filled payload.
|
||||
*
|
||||
* Note: This uid is an internal uid and cannot be counted on to
|
||||
* provide an accurate counter of how many "simulated packets" of a
|
||||
* particular protocol are in the system. It is not trivial to make
|
||||
* this uid into such a counter, because of questions such as what
|
||||
* should the uid be when the packet is sent over broadcast media, or
|
||||
* when fragmentation occurs. If a user wants to trace actual packet
|
||||
* counts, he or she should look at e.g. the IP ID field or transport
|
||||
* sequence numbers, or other packet or frame counters at other
|
||||
* protocol layers.
|
||||
*
|
||||
* \returns an integer identifier which uniquely
|
||||
* identifies this packet.
|
||||
*/
|
||||
|
||||
@@ -496,6 +496,8 @@ DefaultValueTest::RunTests (void)
|
||||
DefaultValueList::Remove ("bool-a");
|
||||
DefaultValueList::Remove ("test-i");
|
||||
DefaultValueList::Remove ("test-c");
|
||||
DefaultValueList::Remove ("test-x");
|
||||
DefaultValueList::Remove ("test-y");
|
||||
DefaultValueList::Remove ("test-ui32");
|
||||
|
||||
return result;
|
||||
|
||||
255
src/core/log.cc
255
src/core/log.cc
@@ -18,6 +18,8 @@
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
// What about print-list!!!!!!???????
|
||||
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
|
||||
#include <list>
|
||||
@@ -44,29 +46,33 @@ ComponentList *GetComponentList (void)
|
||||
return &components;
|
||||
}
|
||||
|
||||
void
|
||||
LogComponentEnableEnvVar (void)
|
||||
LogComponent::LogComponent (char const * name)
|
||||
: m_levels (0), m_name (name)
|
||||
{
|
||||
static bool isFirstLog = true;
|
||||
if (!isFirstLog)
|
||||
EnvVarCheck (name);
|
||||
|
||||
ComponentList *components = GetComponentList ();
|
||||
for (ComponentListI i = components->begin ();
|
||||
i != components->end ();
|
||||
i++)
|
||||
{
|
||||
return;
|
||||
NS_ASSERT (i->first != name);
|
||||
}
|
||||
components->push_back (std::make_pair (name, this));
|
||||
}
|
||||
|
||||
void
|
||||
LogComponent::EnvVarCheck (char const * name)
|
||||
{
|
||||
#ifdef HAVE_GETENV
|
||||
char *envVar = getenv("NS_LOG");
|
||||
if (envVar == 0)
|
||||
{
|
||||
isFirstLog = false;
|
||||
return;
|
||||
}
|
||||
std::string env = envVar;
|
||||
if (env == "print-list")
|
||||
{
|
||||
LogComponentPrintList ();
|
||||
isFirstLog = false;
|
||||
return;
|
||||
}
|
||||
bool allFound = true;
|
||||
std::string myName = name;
|
||||
|
||||
std::string::size_type cur = 0;
|
||||
std::string::size_type next = 0;
|
||||
while (true)
|
||||
@@ -88,106 +94,101 @@ LogComponentEnableEnvVar (void)
|
||||
}
|
||||
std::string::size_type equal = tmp.find ("=");
|
||||
std::string component;
|
||||
int level;
|
||||
if (equal == std::string::npos)
|
||||
{
|
||||
component = tmp;
|
||||
level = LOG_DEBUG;
|
||||
if (component == myName || component == "*")
|
||||
{
|
||||
Enable (LOG_DEBUG);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
component = tmp.substr (0, equal);
|
||||
std::string::size_type cur_lev;
|
||||
std::string::size_type next_lev = equal;
|
||||
do
|
||||
if (component == myName || component == "*")
|
||||
{
|
||||
cur_lev = next_lev + 1;
|
||||
next_lev = tmp.find ("|", cur_lev);
|
||||
std::string lev = tmp.substr (cur_lev, next_lev - cur_lev);
|
||||
if (lev == "error")
|
||||
int level = 0;
|
||||
std::string::size_type cur_lev;
|
||||
std::string::size_type next_lev = equal;
|
||||
do
|
||||
{
|
||||
level |= LOG_ERROR;
|
||||
}
|
||||
else if (lev == "warn")
|
||||
{
|
||||
level |= LOG_WARN;
|
||||
}
|
||||
else if (lev == "debug")
|
||||
{
|
||||
level |= LOG_DEBUG;
|
||||
}
|
||||
else if (lev == "info")
|
||||
{
|
||||
level |= LOG_INFO;
|
||||
}
|
||||
else if (lev == "function")
|
||||
{
|
||||
level |= LOG_FUNCTION;
|
||||
}
|
||||
else if (lev == "param")
|
||||
{
|
||||
level |= LOG_PARAM;
|
||||
}
|
||||
else if (lev == "logic")
|
||||
{
|
||||
level |= LOG_LOGIC;
|
||||
}
|
||||
else if (lev == "all")
|
||||
{
|
||||
level |= LOG_ALL;
|
||||
}
|
||||
else if (lev == "errorlevel")
|
||||
{
|
||||
level |= LOG_LEVEL_ERROR;
|
||||
}
|
||||
else if (lev == "warnlevel")
|
||||
{
|
||||
level |= LOG_LEVEL_WARN;
|
||||
}
|
||||
else if (lev == "debuglevel")
|
||||
{
|
||||
level |= LOG_LEVEL_DEBUG;
|
||||
}
|
||||
else if (lev == "infolevel")
|
||||
{
|
||||
level |= LOG_LEVEL_INFO;
|
||||
}
|
||||
else if (lev == "functionlevel")
|
||||
{
|
||||
level |= LOG_LEVEL_FUNCTION;
|
||||
}
|
||||
else if (lev == "paramlevel")
|
||||
{
|
||||
level |= LOG_LEVEL_PARAM;
|
||||
}
|
||||
else if (lev == "logiclevel")
|
||||
{
|
||||
level |= LOG_LEVEL_LOGIC;
|
||||
}
|
||||
else if (lev == "alllevel")
|
||||
{
|
||||
level |= LOG_LEVEL_ALL;
|
||||
}
|
||||
} while (next_lev != std::string::npos);
|
||||
}
|
||||
bool found = false;
|
||||
ComponentList *components = GetComponentList ();
|
||||
for (ComponentListI i = components->begin ();
|
||||
i != components->end ();
|
||||
i++)
|
||||
{
|
||||
if (i->first.compare (component) == 0)
|
||||
{
|
||||
found = true;
|
||||
|
||||
i->second->Enable ((enum LogLevel)level);
|
||||
break;
|
||||
cur_lev = next_lev + 1;
|
||||
next_lev = tmp.find ("|", cur_lev);
|
||||
std::string lev = tmp.substr (cur_lev, next_lev - cur_lev);
|
||||
if (lev == "error")
|
||||
{
|
||||
level |= LOG_ERROR;
|
||||
}
|
||||
else if (lev == "warn")
|
||||
{
|
||||
level |= LOG_WARN;
|
||||
}
|
||||
else if (lev == "debug")
|
||||
{
|
||||
level |= LOG_DEBUG;
|
||||
}
|
||||
else if (lev == "info")
|
||||
{
|
||||
level |= LOG_INFO;
|
||||
}
|
||||
else if (lev == "function")
|
||||
{
|
||||
level |= LOG_FUNCTION;
|
||||
}
|
||||
else if (lev == "param")
|
||||
{
|
||||
level |= LOG_PARAM;
|
||||
}
|
||||
else if (lev == "logic")
|
||||
{
|
||||
level |= LOG_LOGIC;
|
||||
}
|
||||
else if (lev == "all")
|
||||
{
|
||||
level |= LOG_ALL;
|
||||
}
|
||||
else if (lev == "prefix")
|
||||
{
|
||||
level |= LOG_PREFIX_ALL;
|
||||
}
|
||||
else if (lev == "level_error")
|
||||
{
|
||||
level |= LOG_LEVEL_ERROR;
|
||||
}
|
||||
else if (lev == "level_warn")
|
||||
{
|
||||
level |= LOG_LEVEL_WARN;
|
||||
}
|
||||
else if (lev == "level_debug")
|
||||
{
|
||||
level |= LOG_LEVEL_DEBUG;
|
||||
}
|
||||
else if (lev == "level_info")
|
||||
{
|
||||
level |= LOG_LEVEL_INFO;
|
||||
}
|
||||
else if (lev == "level_function")
|
||||
{
|
||||
level |= LOG_LEVEL_FUNCTION;
|
||||
}
|
||||
else if (lev == "level_param")
|
||||
{
|
||||
level |= LOG_LEVEL_PARAM;
|
||||
}
|
||||
else if (lev == "level_logic")
|
||||
{
|
||||
level |= LOG_LEVEL_LOGIC;
|
||||
}
|
||||
else if (lev == "level_all")
|
||||
{
|
||||
level |= LOG_LEVEL_ALL;
|
||||
}
|
||||
} while (next_lev != std::string::npos);
|
||||
|
||||
Enable ((enum LogLevel)level);
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
allFound = false;
|
||||
}
|
||||
if (next == std::string::npos)
|
||||
{
|
||||
break;
|
||||
@@ -198,31 +199,14 @@ LogComponentEnableEnvVar (void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allFound)
|
||||
{
|
||||
isFirstLog = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
LogComponent::LogComponent (char const * name)
|
||||
: m_levels (0)
|
||||
{
|
||||
ComponentList *components = GetComponentList ();
|
||||
for (ComponentListI i = components->begin ();
|
||||
i != components->end ();
|
||||
i++)
|
||||
{
|
||||
NS_ASSERT (i->first != name);
|
||||
}
|
||||
components->push_back (std::make_pair (name, this));
|
||||
}
|
||||
|
||||
bool
|
||||
LogComponent::IsEnabled (enum LogLevel level) const
|
||||
{
|
||||
LogComponentEnableEnvVar ();
|
||||
// LogComponentEnableEnvVar ();
|
||||
return (level & m_levels) ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -244,6 +228,13 @@ LogComponent::Disable (enum LogLevel level)
|
||||
m_levels &= ~level;
|
||||
}
|
||||
|
||||
char const *
|
||||
LogComponent::Name (void) const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LogComponentEnable (char const *name, enum LogLevel level)
|
||||
{
|
||||
@@ -260,6 +251,18 @@ LogComponentEnable (char const *name, enum LogLevel level)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogComponentEnableAll (enum LogLevel level)
|
||||
{
|
||||
ComponentList *components = GetComponentList ();
|
||||
for (ComponentListI i = components->begin ();
|
||||
i != components->end ();
|
||||
i++)
|
||||
{
|
||||
i->second->Enable (level);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogComponentDisable (char const *name, enum LogLevel level)
|
||||
{
|
||||
@@ -276,6 +279,18 @@ LogComponentDisable (char const *name, enum LogLevel level)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogComponentDisableAll (enum LogLevel level)
|
||||
{
|
||||
ComponentList *components = GetComponentList ();
|
||||
for (ComponentListI i = components->begin ();
|
||||
i != components->end ();
|
||||
i++)
|
||||
{
|
||||
i->second->Disable (level);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogComponentPrintList (void)
|
||||
{
|
||||
|
||||
130
src/core/log.h
130
src/core/log.h
@@ -32,22 +32,23 @@
|
||||
* send information out on screen. All logging messages
|
||||
* are disabled by default. To enable selected logging
|
||||
* messages, use the ns3::LogComponentEnable
|
||||
* function.
|
||||
*
|
||||
* Alternatively, you can use the NS_LOG
|
||||
* environment variable to define a ';'-separated list of
|
||||
* function or use the NS_LOG environment variable and
|
||||
* ns3::LogComponentEnableEnvVar
|
||||
*
|
||||
* Use the environment variable NS_LOG to define a ';'-separated list of
|
||||
* logging components to enable. For example, NS_LOG=a;b;c;DAFD;GH
|
||||
* would enable the components 'a', 'b', 'c', 'DAFD', and, 'GH'.
|
||||
* NS_LOG=* will enable all available log components.
|
||||
*
|
||||
* For each component, the "debug" log level is enabled by default
|
||||
* but more components can be enabled selectively with the following
|
||||
* syntax: NS_LOG='Component1=func|param|warn;Component2=error|debug'
|
||||
* This example would enable the 'func', 'param', and 'warn' log
|
||||
* levels for 'Component1' and the 'error' and 'debug' log levels
|
||||
* for 'Component2'.
|
||||
* for 'Component2'. The wildcard can be used here as well. For example
|
||||
* NS_LOG='*=level_all|prefix' would enable all log levels and prefix all
|
||||
* prints with the component and function names.
|
||||
*
|
||||
* The list of available log components can be printed on stdout
|
||||
* with the NS_LOG=print-list syntax.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -92,20 +93,25 @@
|
||||
{ \
|
||||
if (g_log.IsEnabled (level)) \
|
||||
{ \
|
||||
std::clog << __PRETTY_FUNCTION__ << " ==> " << \
|
||||
msg << std::endl; \
|
||||
if (g_log.IsEnabled (ns3::LOG_PREFIX_ALL)) \
|
||||
{ \
|
||||
std::clog << g_log.Name () << ":" << \
|
||||
__FUNCTION__ << "(): "; \
|
||||
} \
|
||||
std::clog << msg << std::endl; \
|
||||
} \
|
||||
} \
|
||||
while (false)
|
||||
|
||||
#define NS_LOG_F(level) \
|
||||
do \
|
||||
{ \
|
||||
if (g_log.IsEnabled (level)) \
|
||||
{ \
|
||||
std::clog << __PRETTY_FUNCTION__ << std::endl;\
|
||||
} \
|
||||
} \
|
||||
#define NS_LOG_F(level) \
|
||||
do \
|
||||
{ \
|
||||
if (g_log.IsEnabled (level)) \
|
||||
{ \
|
||||
std::clog << g_log.Name () << ":" << __FUNCTION__ << \
|
||||
"()" << std::endl; \
|
||||
} \
|
||||
} \
|
||||
while (false)
|
||||
|
||||
#define NS_LOG_ERROR(msg) \
|
||||
@@ -129,9 +135,6 @@
|
||||
#define NS_LOG_LOGIC(msg) \
|
||||
NS_LOG(ns3::LOG_LOGIC, msg)
|
||||
|
||||
#define NS_LOG_ALL(msg) \
|
||||
NS_LOG(ns3::LOG_ALL, msg)
|
||||
|
||||
#define NS_LOG_UNCOND(msg) \
|
||||
do \
|
||||
{ \
|
||||
@@ -150,7 +153,6 @@
|
||||
#define NS_LOG_FUNCTION
|
||||
#define NS_LOG_PARAM(msg)
|
||||
#define NS_LOG_LOGIC(msg)
|
||||
#define NS_LOG_ALL(msg)
|
||||
#define NS_LOG_UNCOND(msg)
|
||||
|
||||
#endif
|
||||
@@ -160,70 +162,95 @@ namespace ns3 {
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
|
||||
enum LogLevel {
|
||||
LOG_ERROR = 0x0001, // serious error messages only
|
||||
LOG_LEVEL_ERROR = 0x0001,
|
||||
LOG_NONE = 0x00000000, // no logging
|
||||
|
||||
LOG_WARN = 0x0002, // warning messages
|
||||
LOG_LEVEL_WARN = 0x0003,
|
||||
LOG_ERROR = 0x00000001, // serious error messages only
|
||||
LOG_LEVEL_ERROR = 0x00000001,
|
||||
|
||||
LOG_DEBUG = 0x0004, // rare ad-hoc debug messages
|
||||
LOG_LEVEL_DEBUG = 0x0007,
|
||||
LOG_WARN = 0x00000002, // warning messages
|
||||
LOG_LEVEL_WARN = 0x00000003,
|
||||
|
||||
LOG_INFO = 0x0008, // informational messages (e.g., banners)
|
||||
LOG_LEVEL_INFO = 0x000f,
|
||||
LOG_DEBUG = 0x00000004, // rare ad-hoc debug messages
|
||||
LOG_LEVEL_DEBUG = 0x00000007,
|
||||
|
||||
LOG_FUNCTION = 0x0010, // function tracing
|
||||
LOG_LEVEL_FUNCTION = 0x001f,
|
||||
LOG_INFO = 0x00000008, // informational messages (e.g., banners)
|
||||
LOG_LEVEL_INFO = 0x0000000f,
|
||||
|
||||
LOG_PARAM = 0x0020, // parameters to functions
|
||||
LOG_LEVEL_PARAM = 0x003f,
|
||||
LOG_FUNCTION = 0x00000010, // function tracing
|
||||
LOG_LEVEL_FUNCTION = 0x0000001f,
|
||||
|
||||
LOG_LOGIC = 0x0040, // control flow tracing within functions
|
||||
LOG_LEVEL_LOGIC = 0x007f,
|
||||
LOG_PARAM = 0x00000020, // parameters to functions
|
||||
LOG_LEVEL_PARAM = 0x0000003f,
|
||||
|
||||
LOG_ALL = 0x4000, // print everything
|
||||
LOG_LEVEL_ALL = 0x7fff
|
||||
LOG_LOGIC = 0x00000040, // control flow tracing within functions
|
||||
LOG_LEVEL_LOGIC = 0x0000007f,
|
||||
|
||||
LOG_ALL = 0x7fffffff, // print everything
|
||||
LOG_LEVEL_ALL = LOG_ALL,
|
||||
|
||||
LOG_PREFIX_ALL = 0x80000000 // prefix all trace prints with function
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
/**
|
||||
* \param name a log component name
|
||||
* \param level a logging level
|
||||
* \param decorate whether or not to add function names to all logs
|
||||
* \ingroup logging
|
||||
*
|
||||
* Enable the logging output associated with that log component.
|
||||
* The logging output can be later disabled with a call
|
||||
* to ns3::LogComponentDisable.
|
||||
*/
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
void LogComponentEnable (char const *name, enum LogLevel level);
|
||||
#else
|
||||
#define LogComponentEnable(a,b)
|
||||
#endif
|
||||
void LogComponentEnable (char const *name, enum LogLevel level);
|
||||
|
||||
/**
|
||||
* \param level a logging level
|
||||
* \param decorate whether or not to add function names to all logs
|
||||
* \ingroup logging
|
||||
*
|
||||
* Enable the logging output for all registered log components.
|
||||
*/
|
||||
void LogComponentEnableAll (enum LogLevel level);
|
||||
#else
|
||||
#define LogComponentEnable(a,b)
|
||||
#define LogComponentEnableAll(a)
|
||||
#endif
|
||||
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
/**
|
||||
* \param name a log component name
|
||||
* \param level a logging level
|
||||
* \ingroup logging
|
||||
*
|
||||
* Disable the logging output associated with that log component.
|
||||
* The logging output can be later re-enabled with a call
|
||||
* to ns3::LogComponentEnable.
|
||||
*/
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
void LogComponentDisable (char const *name, enum LogLevel level);
|
||||
|
||||
/**
|
||||
* \param name a log component name
|
||||
* \param level a logging level
|
||||
* \ingroup logging
|
||||
*
|
||||
* Disable the logging output associated with that log component.
|
||||
* The logging output can be later re-enabled with a call
|
||||
* to ns3::LogComponentEnable.
|
||||
*/
|
||||
void LogComponentDisableAll (enum LogLevel level);
|
||||
|
||||
#else
|
||||
#define LogComponentDisable(a,b)
|
||||
#define LogComponentDisableAll(a)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \ingroup logging
|
||||
*
|
||||
* Print the list of logging messages available.
|
||||
* The output of this function can be obtained by setting
|
||||
* the NS_LOG environment variable to the special value
|
||||
* 'print-list'.
|
||||
*
|
||||
* For example: NS_LOG=print-list
|
||||
*/
|
||||
#ifdef NS3_LOG_ENABLE
|
||||
void LogComponentPrintList (void);
|
||||
@@ -236,12 +263,17 @@ void LogComponentPrintList (void);
|
||||
class LogComponent {
|
||||
public:
|
||||
LogComponent (char const *name);
|
||||
void EnvVarCheck (char const *name);
|
||||
bool IsEnabled (enum LogLevel level) const;
|
||||
bool IsNoneEnabled (void) const;
|
||||
void Enable (enum LogLevel level);
|
||||
void Disable (enum LogLevel level);
|
||||
bool Decorate (void) const;
|
||||
char const *Name (void) const;
|
||||
private:
|
||||
int32_t m_levels;
|
||||
int32_t m_levels;
|
||||
char const *m_name;
|
||||
bool m_decorate;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -96,7 +96,8 @@ CsmaIpv4Topology::AddIpv4Address(
|
||||
Ptr<Node> node,
|
||||
uint32_t netDeviceNumber,
|
||||
const Ipv4Address address,
|
||||
const Ipv4Mask mask)
|
||||
const Ipv4Mask mask,
|
||||
uint16_t metric)
|
||||
{
|
||||
Ptr<NetDevice> nd = node->GetDevice(netDeviceNumber);
|
||||
|
||||
@@ -105,6 +106,7 @@ CsmaIpv4Topology::AddIpv4Address(
|
||||
|
||||
ipv4->SetAddress (ifIndex, address);
|
||||
ipv4->SetNetworkMask (ifIndex, mask);
|
||||
ipv4->SetMetric (ifIndex, metric);
|
||||
ipv4->SetUp (ifIndex);
|
||||
return ifIndex;
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ public:
|
||||
* the address.
|
||||
* \param address The Ipv4 Address for the interface.
|
||||
* \param network The network mask for the interface
|
||||
* \param metric (optional) metric (cost) to assign for routing calculations
|
||||
*
|
||||
* Add an Ipv4Address to the Ipv4 interface associated with the
|
||||
* ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel
|
||||
@@ -110,7 +111,8 @@ public:
|
||||
static uint32_t AddIpv4Address(Ptr<Node> node,
|
||||
uint32_t netDeviceNumber,
|
||||
const Ipv4Address address,
|
||||
const Ipv4Mask mask);
|
||||
const Ipv4Mask mask,
|
||||
uint16_t metric = 1);
|
||||
|
||||
/**
|
||||
* \param nd1 Node
|
||||
|
||||
@@ -103,6 +103,59 @@ PointToPointTopology::AddIpv4Addresses(
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointTopology::SetIpv4Metric(
|
||||
Ptr<const PointToPointChannel> chan,
|
||||
Ptr<Node> n1, Ptr<Node> n2, const uint16_t metric)
|
||||
{
|
||||
|
||||
// The PointToPoint channel is used to find the relevant NetDevices
|
||||
NS_ASSERT (chan->GetNDevices () == 2);
|
||||
Ptr<NetDevice> nd1 = chan->GetDevice (0);
|
||||
Ptr<NetDevice> nd2 = chan->GetDevice (1);
|
||||
// Make sure that nd1 belongs to n1 and nd2 to n2
|
||||
if ( (nd1->GetNode ()->GetId () == n2->GetId () ) &&
|
||||
(nd2->GetNode ()->GetId () == n1->GetId () ) )
|
||||
{
|
||||
std::swap(nd1, nd2);
|
||||
}
|
||||
NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
|
||||
NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
|
||||
|
||||
// The NetDevice ifIndex does not correspond to the
|
||||
// ifIndex used by Ipv4. Therefore, we have to iterate
|
||||
// through the NetDevices until we find the Ipv4 ifIndex
|
||||
// that corresponds to NetDevice nd1
|
||||
// Get interface indexes for both nodes corresponding to the right channel
|
||||
uint32_t index = 0;
|
||||
bool found = false;
|
||||
Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
|
||||
{
|
||||
if (ip1 ->GetNetDevice (i) == nd1)
|
||||
{
|
||||
index = i;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
NS_ASSERT(found);
|
||||
ip1->SetMetric (index, metric);
|
||||
|
||||
index = 0;
|
||||
found = false;
|
||||
Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
|
||||
for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
|
||||
{
|
||||
if (ip2 ->GetNetDevice (i) == nd2)
|
||||
{
|
||||
index = i;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
NS_ASSERT(found);
|
||||
ip2->SetMetric (index, metric);
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointTopology::AddIpv4Routes (
|
||||
Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
|
||||
|
||||
@@ -70,6 +70,20 @@ public:
|
||||
Ptr<Node> n1, const Ipv4Address& addr1,
|
||||
Ptr<Node> n2, const Ipv4Address& addr2);
|
||||
|
||||
/**
|
||||
* \param chan PointToPointChannel to use
|
||||
* \param n1 Node
|
||||
* \param n2 Node
|
||||
* \param metric link metric to assign on Ipv4Link on chan between n1 and n2
|
||||
*
|
||||
* Add a non-unit-cost link metric (bidirectionally) to the Ipv4
|
||||
* interfaces associated with the two PointToPointNetDevices on the
|
||||
* provided PointToPointChannel
|
||||
*/
|
||||
static void SetIpv4Metric(
|
||||
Ptr<const PointToPointChannel> chan,
|
||||
Ptr<Node> n1, Ptr<Node> n2, const uint16_t metric);
|
||||
|
||||
/**
|
||||
* \param channel PointToPointChannel to use
|
||||
* \param n1 Node
|
||||
|
||||
@@ -201,6 +201,18 @@ Ipv4Impl::GetAddress (uint32_t i) const
|
||||
return m_ipv4->GetAddress (i);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Impl::SetMetric (uint32_t i, uint16_t metric)
|
||||
{
|
||||
m_ipv4->SetMetric (i, metric);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Ipv4Impl::GetMetric (uint32_t i) const
|
||||
{
|
||||
return m_ipv4->GetMetric (i);
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4Impl::GetIfIndexForDestination (Ipv4Address dest, uint32_t &ifIndex) const
|
||||
{
|
||||
|
||||
@@ -88,6 +88,8 @@ public:
|
||||
virtual void SetNetworkMask (uint32_t i, Ipv4Mask mask);
|
||||
virtual Ipv4Mask GetNetworkMask (uint32_t t) const;
|
||||
virtual Ipv4Address GetAddress (uint32_t i) const;
|
||||
virtual void SetMetric (uint32_t i, uint16_t metric);
|
||||
virtual uint16_t GetMetric (uint32_t i) const;
|
||||
virtual Ipv4Address GetSourceAddress (Ipv4Address destination) const;
|
||||
virtual bool GetIfIndexForDestination (Ipv4Address dest,
|
||||
uint32_t &ifIndex) const;
|
||||
|
||||
@@ -37,7 +37,8 @@ namespace ns3 {
|
||||
*/
|
||||
Ipv4Interface::Ipv4Interface (Ptr<NetDevice> nd)
|
||||
: m_netdevice (nd),
|
||||
m_ifup(false)
|
||||
m_ifup(false),
|
||||
m_metric(1)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << &nd << ")");
|
||||
@@ -96,6 +97,21 @@ Ipv4Interface::GetNetworkMask (void) const
|
||||
return m_netmask;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetMetric (uint16_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << metric << ")");
|
||||
m_metric = metric;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Ipv4Interface::GetMetric (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
return m_metric;
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4Interface::GetAddress (void) const
|
||||
{
|
||||
|
||||
@@ -96,6 +96,14 @@ public:
|
||||
* \returns the ipv4 netmask of this interface
|
||||
*/
|
||||
Ipv4Mask GetNetworkMask (void) const;
|
||||
/**
|
||||
* \param configured routing metric (cost) of this interface
|
||||
*/
|
||||
void SetMetric (uint16_t);
|
||||
/**
|
||||
* \returns configured routing metric (cost) of this interface
|
||||
*/
|
||||
uint16_t GetMetric (void) const;
|
||||
/**
|
||||
* \returns the ipv4 address of this interface
|
||||
*/
|
||||
@@ -147,6 +155,7 @@ private:
|
||||
bool m_ifup;
|
||||
Ipv4Address m_address;
|
||||
Ipv4Mask m_netmask;
|
||||
uint16_t m_metric;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -821,6 +821,24 @@ Ipv4L3Protocol::GetAddress (uint32_t i) const
|
||||
return interface->GetAddress ();
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3Protocol::SetMetric (uint32_t i, uint16_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << i << ", " << metric << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
interface->SetMetric (metric);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
Ipv4L3Protocol::GetMetric (uint32_t i) const
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
NS_LOG_PARAM ("(" << i << ")");
|
||||
Ptr<Ipv4Interface> interface = GetInterface (i);
|
||||
return interface->GetMetric ();
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4L3Protocol::GetIfIndexForDestination (
|
||||
Ipv4Address destination, uint32_t& ifIndex) const
|
||||
|
||||
@@ -198,6 +198,8 @@ public:
|
||||
void SetNetworkMask (uint32_t i, Ipv4Mask mask);
|
||||
Ipv4Mask GetNetworkMask (uint32_t t) const;
|
||||
Ipv4Address GetAddress (uint32_t i) const;
|
||||
void SetMetric (uint32_t i, uint16_t metric);
|
||||
uint16_t GetMetric (uint32_t i) const;
|
||||
bool GetIfIndexForDestination (Ipv4Address destination,
|
||||
uint32_t& ifIndex) const;
|
||||
uint16_t GetMtu (uint32_t i) const;
|
||||
|
||||
@@ -151,16 +151,6 @@ Ipv4Address::Set (char const *address)
|
||||
m_address = AsciiToIpv4Host (address);
|
||||
}
|
||||
|
||||
bool
|
||||
Ipv4Address::IsEqual (Ipv4Address other) const
|
||||
{
|
||||
if (other.m_address == m_address) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4Address::CombineMask (Ipv4Mask const &mask) const
|
||||
{
|
||||
@@ -296,19 +286,6 @@ Ipv4Address::GetLoopback (void)
|
||||
return loopback;
|
||||
}
|
||||
|
||||
bool operator == (Ipv4Address const &a, Ipv4Address const &b)
|
||||
{
|
||||
return a.IsEqual (b);
|
||||
}
|
||||
bool operator != (Ipv4Address const &a, Ipv4Address const &b)
|
||||
{
|
||||
return !a.IsEqual (b);
|
||||
}
|
||||
bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB)
|
||||
{
|
||||
return (addrA.GetHostOrder () < addrB.GetHostOrder ());
|
||||
}
|
||||
|
||||
size_t Ipv4AddressHash::operator()(Ipv4Address const &x) const
|
||||
{
|
||||
return x.GetHostOrder ();
|
||||
|
||||
@@ -73,7 +73,10 @@ public:
|
||||
* \param other address to which to compare this address
|
||||
* \return True if the addresses are equal. False otherwise.
|
||||
*/
|
||||
bool IsEqual (Ipv4Address other) const;
|
||||
bool IsEqual (const Ipv4Address &other) const
|
||||
{
|
||||
return m_address == other.m_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the host-order 32-bit IP address
|
||||
@@ -142,6 +145,10 @@ private:
|
||||
Address ConvertTo (void) const;
|
||||
static uint8_t GetType (void);
|
||||
uint32_t m_address;
|
||||
|
||||
friend bool operator == (Ipv4Address const &a, Ipv4Address const &b);
|
||||
friend bool operator != (Ipv4Address const &a, Ipv4Address const &b);
|
||||
friend bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB);
|
||||
};
|
||||
|
||||
|
||||
@@ -177,9 +184,19 @@ private:
|
||||
std::ostream& operator<< (std::ostream& os, Ipv4Address const& address);
|
||||
std::ostream& operator<< (std::ostream& os, Ipv4Mask const& mask);
|
||||
|
||||
bool operator == (Ipv4Address const &a, Ipv4Address const &b);
|
||||
bool operator != (Ipv4Address const &a, Ipv4Address const &b);
|
||||
bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB);
|
||||
inline bool operator == (const Ipv4Address &a, const Ipv4Address &b)
|
||||
{
|
||||
return (a.m_address == b.m_address);
|
||||
}
|
||||
inline bool operator != (const Ipv4Address &a, const Ipv4Address &b)
|
||||
{
|
||||
return (a.m_address != b.m_address);
|
||||
}
|
||||
inline bool operator < (const Ipv4Address &a, const Ipv4Address &b)
|
||||
{
|
||||
return (a.m_address < b.m_address);
|
||||
}
|
||||
|
||||
|
||||
class Ipv4AddressHash : public std::unary_function<Ipv4Address, size_t> {
|
||||
public:
|
||||
|
||||
@@ -383,6 +383,20 @@ public:
|
||||
*/
|
||||
virtual Ipv4Mask GetNetworkMask (uint32_t i) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \param metric routing metric (cost) associated to the underlying
|
||||
* ipv4 interface
|
||||
*/
|
||||
virtual void SetMetric (uint32_t i, uint16_t metric) = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \returns routing metric (cost) associated to the underlying
|
||||
* ipv4 interface
|
||||
*/
|
||||
virtual uint16_t GetMetric (uint32_t i) const = 0;
|
||||
|
||||
/**
|
||||
* \param i index of ipv4 interface
|
||||
* \returns the address associated to the underlying ipv4 interface
|
||||
|
||||
@@ -529,7 +529,8 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
|
||||
// Get w_lsa: In case of V is Router-LSA
|
||||
if (v->GetVertexType () == SPFVertex::VertexRouter)
|
||||
{
|
||||
NS_LOG_LOGIC ("Examining " << v->GetVertexId () << "'s " <<
|
||||
NS_LOG_LOGIC ("Examining link " << i << " of " <<
|
||||
v->GetVertexId () << "'s " <<
|
||||
v->GetLSA ()->GetNLinkRecords () << " link records");
|
||||
//
|
||||
// (a) If this is a link to a stub network, examine the next link in V's LSA.
|
||||
@@ -637,7 +638,8 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
|
||||
candidate.Push (w);
|
||||
NS_LOG_LOGIC ("Pushing " <<
|
||||
w->GetVertexId () << ", parent vertexId: " <<
|
||||
v->GetVertexId ());
|
||||
v->GetVertexId () << ", distance: " <<
|
||||
w->GetDistanceFromRoot ());
|
||||
}
|
||||
}
|
||||
else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
|
||||
@@ -688,7 +690,7 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
|
||||
}
|
||||
|
||||
//
|
||||
// This method is derived from quagga ospf_next_hop_calculation() 16.1.1.
|
||||
// This method is derived from quagga ospf_nexthop_calculation() 16.1.1.
|
||||
//
|
||||
// Calculate nexthop from root through V (parent) to vertex W (destination)
|
||||
// with given distance from root->W.
|
||||
@@ -784,11 +786,13 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
|
||||
//
|
||||
w->SetOutgoingInterfaceId (
|
||||
FindOutgoingInterfaceId (l->GetLinkData ()));
|
||||
|
||||
w->SetDistanceFromRoot (distance);
|
||||
w->SetParent (v);
|
||||
NS_LOG_LOGIC ("Next hop from " <<
|
||||
v->GetVertexId () << " to " << w->GetVertexId () <<
|
||||
" goes through next hop " << w->GetNextHop () <<
|
||||
" via outgoing interface " << w->GetOutgoingInterfaceId ());
|
||||
" via outgoing interface " << w->GetOutgoingInterfaceId () <<
|
||||
" with distance " << distance);
|
||||
} // end W is a router vertes
|
||||
else
|
||||
{
|
||||
@@ -804,7 +808,8 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
|
||||
w->SetParent (v);
|
||||
NS_LOG_LOGIC ("Next hop from " <<
|
||||
v->GetVertexId () << " to network " << w->GetVertexId () <<
|
||||
" via outgoing interface " << w->GetOutgoingInterfaceId ());
|
||||
" via outgoing interface " << w->GetOutgoingInterfaceId () <<
|
||||
" with distance " << distance);
|
||||
return 1;
|
||||
}
|
||||
} // end v is the root
|
||||
@@ -997,6 +1002,7 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
|
||||
m_spfroot= v;
|
||||
v->SetDistanceFromRoot (0);
|
||||
v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
|
||||
NS_LOG_LOGIC ("Starting SPFCalculate for node " << root);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
|
||||
LinkType linkType,
|
||||
Ipv4Address linkId,
|
||||
Ipv4Address linkData,
|
||||
uint32_t metric)
|
||||
uint16_t metric)
|
||||
:
|
||||
m_linkId (linkId),
|
||||
m_linkData (linkData),
|
||||
@@ -110,7 +110,7 @@ GlobalRoutingLinkRecord::SetLinkType (
|
||||
m_linkType = linkType;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
uint16_t
|
||||
GlobalRoutingLinkRecord::GetMetric (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
@@ -118,7 +118,7 @@ GlobalRoutingLinkRecord::GetMetric (void) const
|
||||
}
|
||||
|
||||
void
|
||||
GlobalRoutingLinkRecord::SetMetric (uint32_t metric)
|
||||
GlobalRoutingLinkRecord::SetMetric (uint16_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION;
|
||||
m_metric = metric;
|
||||
@@ -202,6 +202,7 @@ GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
|
||||
pDst->SetLinkType (pSrc->GetLinkType ());
|
||||
pDst->SetLinkId (pSrc->GetLinkId ());
|
||||
pDst->SetLinkData (pSrc->GetLinkData ());
|
||||
pDst->SetMetric (pSrc->GetMetric ());
|
||||
|
||||
m_linkRecords.push_back(pDst);
|
||||
pDst = 0;
|
||||
@@ -397,6 +398,7 @@ GlobalRoutingLSA::Print (std::ostream &os) const
|
||||
os << "----------" << std::endl;
|
||||
os << "m_linkId = " << p->GetLinkId () << std::endl;
|
||||
os << "m_linkData = " << p->GetLinkData () << std::endl;
|
||||
os << "m_metric = " << p->GetMetric () << std::endl;
|
||||
}
|
||||
}
|
||||
else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
|
||||
@@ -547,6 +549,7 @@ GlobalRouter::DiscoverLSAs (void)
|
||||
Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
|
||||
Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
|
||||
NS_LOG_LOGIC ("Working with local address " << addrLocal);
|
||||
uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
|
||||
//
|
||||
// Now, we're going to walk over to the remote net device on the other end of
|
||||
// the point-to-point channel we now know we have. This is where our adjacent
|
||||
@@ -566,8 +569,7 @@ GlobalRouter::DiscoverLSAs (void)
|
||||
Ipv4Address maskLocalAddr;
|
||||
maskLocalAddr.Set(maskLocal.GetHostOrder ());
|
||||
plr->SetLinkData (maskLocalAddr);
|
||||
// Cost is interface's configured output cost (NOTYET)
|
||||
plr->SetMetric (1);
|
||||
plr->SetMetric (metricLocal);
|
||||
pLSA->AddLinkRecord(plr);
|
||||
plr = 0;
|
||||
continue;
|
||||
@@ -589,8 +591,7 @@ GlobalRouter::DiscoverLSAs (void)
|
||||
plr->SetLinkId (desigRtr);
|
||||
// Link Data is router's own IP address
|
||||
plr->SetLinkData (addrLocal);
|
||||
// Cost is interface's configured output cost (NOTYET)
|
||||
plr->SetMetric (1);
|
||||
plr->SetMetric (metricLocal);
|
||||
pLSA->AddLinkRecord (plr);
|
||||
plr = 0;
|
||||
continue;
|
||||
@@ -613,6 +614,7 @@ GlobalRouter::DiscoverLSAs (void)
|
||||
Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
|
||||
Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
|
||||
NS_LOG_LOGIC ("Working with local address " << addrLocal);
|
||||
uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
|
||||
//
|
||||
// Now, we're going to walk over to the remote net device on the other end of
|
||||
// the point-to-point channel we now know we have. This is where our adjacent
|
||||
@@ -659,6 +661,7 @@ GlobalRouter::DiscoverLSAs (void)
|
||||
plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
|
||||
plr->SetLinkId (rtrIdRemote);
|
||||
plr->SetLinkData (addrLocal);
|
||||
plr->SetMetric (metricLocal);
|
||||
pLSA->AddLinkRecord (plr);
|
||||
plr = 0;
|
||||
|
||||
@@ -666,6 +669,7 @@ GlobalRouter::DiscoverLSAs (void)
|
||||
plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
|
||||
plr->SetLinkId (addrRemote);
|
||||
plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown
|
||||
plr->SetMetric (metricLocal);
|
||||
pLSA->AddLinkRecord (plr);
|
||||
plr = 0;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
LinkType linkType,
|
||||
Ipv4Address linkId,
|
||||
Ipv4Address linkData,
|
||||
uint32_t metric);
|
||||
uint16_t metric);
|
||||
|
||||
/**
|
||||
* @brief Destroy a Global Routing Link Record.
|
||||
@@ -176,7 +176,7 @@ public:
|
||||
*
|
||||
* @returns The metric field of the Global Routing Link Record.
|
||||
*/
|
||||
uint32_t GetMetric(void) const;
|
||||
uint16_t GetMetric(void) const;
|
||||
|
||||
/**
|
||||
* @brief Set the Metric Data field of the Global Routing Link Record.
|
||||
@@ -189,7 +189,7 @@ public:
|
||||
*
|
||||
* @param metric The new metric for the current Global Routing Link Record.
|
||||
*/
|
||||
void SetMetric(uint32_t metric);
|
||||
void SetMetric(uint16_t metric);
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -230,7 +230,7 @@ private:
|
||||
* of two hops relate to the cost of sending a packet); rather you should
|
||||
* use something like delay.
|
||||
*/
|
||||
uint32_t m_metric;
|
||||
uint16_t m_metric;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
* 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
|
||||
@@ -34,17 +33,11 @@ EventGarbageCollector::EventGarbageCollector () :
|
||||
void
|
||||
EventGarbageCollector::Track (EventId event)
|
||||
{
|
||||
m_events.push_back (event);
|
||||
m_events.insert (event);
|
||||
if (m_events.size () >= m_nextCleanupSize)
|
||||
Cleanup ();
|
||||
}
|
||||
|
||||
inline bool
|
||||
EventExpiredPredicate (const EventId &event)
|
||||
{
|
||||
return event.IsExpired ();
|
||||
}
|
||||
|
||||
void
|
||||
EventGarbageCollector::Grow ()
|
||||
{
|
||||
@@ -64,7 +57,15 @@ EventGarbageCollector::Shrink ()
|
||||
void
|
||||
EventGarbageCollector::Cleanup ()
|
||||
{
|
||||
m_events.remove_if (EventExpiredPredicate);
|
||||
for (EventList::iterator iter = m_events.begin (); iter != m_events.end ();)
|
||||
{
|
||||
if ((*iter).IsExpired ())
|
||||
{
|
||||
m_events.erase (iter++);
|
||||
}
|
||||
else
|
||||
break; // EventIds are sorted by timestamp => further events are not expired for sure
|
||||
}
|
||||
|
||||
// If after cleanup we are still over the limit, increase the limit.
|
||||
if (m_events.size () >= m_nextCleanupSize)
|
||||
@@ -76,7 +77,7 @@ EventGarbageCollector::Cleanup ()
|
||||
|
||||
EventGarbageCollector::~EventGarbageCollector ()
|
||||
{
|
||||
for (std::list<EventId>::iterator event = m_events.begin ();
|
||||
for (EventList::iterator event = m_events.begin ();
|
||||
event != m_events.end (); event++)
|
||||
{
|
||||
Simulator::Cancel (*event);
|
||||
@@ -1,7 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
* 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
|
||||
@@ -21,9 +20,9 @@
|
||||
#ifndef EVENT_GARBAGE_COLLECTOR_H
|
||||
#define EVENT_GARBAGE_COLLECTOR_H
|
||||
|
||||
#include <list>
|
||||
#include "event-id.h"
|
||||
#include "simulator.h"
|
||||
#include <set>
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -49,8 +48,18 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
std::list<EventId>::size_type m_nextCleanupSize;
|
||||
std::list<EventId> m_events;
|
||||
struct EventIdLessThanTs
|
||||
{
|
||||
bool operator () (const EventId &a, const EventId &b) const
|
||||
{
|
||||
return (a.GetTs () < b.GetTs ());
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::multiset<EventId, EventIdLessThanTs> EventList;
|
||||
|
||||
EventList::size_type m_nextCleanupSize;
|
||||
EventList m_events;
|
||||
|
||||
void Cleanup ();
|
||||
void Grow ();
|
||||
2110
src/routing/olsr/olsr-agent-impl.cc
Normal file
2110
src/routing/olsr/olsr-agent-impl.cc
Normal file
File diff suppressed because it is too large
Load Diff
184
src/routing/olsr/olsr-agent-impl.h
Normal file
184
src/routing/olsr/olsr-agent-impl.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004 Francisco J. Ros
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Francisco J. Ros <fjrm@dif.um.es>
|
||||
* Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __OLSR_AGENT_IMPL_H__
|
||||
#define __OLSR_AGENT_IMPL_H__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "olsr-agent.h"
|
||||
#include "olsr-header.h"
|
||||
#include "olsr-state.h"
|
||||
|
||||
#include "routing-table.h"
|
||||
#include "repositories.h"
|
||||
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "event-garbage-collector.h"
|
||||
#include "ns3/timer.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
using namespace olsr;
|
||||
|
||||
|
||||
class OlsrAgentImpl : public OlsrAgent
|
||||
{
|
||||
friend class OlsrTest;
|
||||
|
||||
public:
|
||||
OlsrAgentImpl (Ptr<Node> node);
|
||||
|
||||
virtual void Start ();
|
||||
virtual void SetMainInterface (uint32_t interface);
|
||||
|
||||
private:
|
||||
EventGarbageCollector m_events;
|
||||
|
||||
/// Address of the routing agent.
|
||||
Ipv4Address m_routingAgentAddr;
|
||||
|
||||
/// Packets sequence number counter.
|
||||
uint16_t m_packetSequenceNumber;
|
||||
/// Messages sequence number counter.
|
||||
uint16_t m_messageSequenceNumber;
|
||||
/// Advertised Neighbor Set sequence number.
|
||||
uint16_t m_ansn;
|
||||
|
||||
/// HELLO messages' emission interval.
|
||||
Time m_helloInterval;
|
||||
/// TC messages' emission interval.
|
||||
Time m_tcInterval;
|
||||
/// MID messages' emission interval.
|
||||
Time m_midInterval;
|
||||
/// Willingness for forwarding packets on behalf of other nodes.
|
||||
uint8_t m_willingness;
|
||||
/// Determines if layer 2 notifications are enabled or not.
|
||||
bool m_useL2Notifications;
|
||||
|
||||
/// Routing table.
|
||||
Ptr<RoutingTable> m_routingTable;
|
||||
/// Internal state with all needed data structs.
|
||||
OlsrState m_state;
|
||||
|
||||
Ptr<Ipv4> m_ipv4;
|
||||
|
||||
protected:
|
||||
void DoDispose ();
|
||||
void SendPacket (Packet packet);
|
||||
|
||||
/// Increments packet sequence number and returns the new value.
|
||||
inline uint16_t GetPacketSequenceNumber ();
|
||||
/// Increments message sequence number and returns the new value.
|
||||
inline uint16_t GetMessageSequenceNumber ();
|
||||
|
||||
void RecvOlsr (Ptr<Socket> socket,
|
||||
const Packet &receivedPacket,
|
||||
const Address &sourceAddress);
|
||||
|
||||
void MprComputation ();
|
||||
void RoutingTableComputation ();
|
||||
Ipv4Address GetMainAddress (Ipv4Address iface_addr);
|
||||
|
||||
// Timer handlers
|
||||
Timer m_helloTimer;
|
||||
void HelloTimerExpire ();
|
||||
|
||||
Timer m_tcTimer;
|
||||
void TcTimerExpire ();
|
||||
|
||||
Timer m_midTimer;
|
||||
void MidTimerExpire ();
|
||||
|
||||
void DupTupleTimerExpire (DuplicateTuple tuple);
|
||||
bool m_linkTupleTimerFirstTime;
|
||||
void LinkTupleTimerExpire (LinkTuple tuple);
|
||||
void Nb2hopTupleTimerExpire (TwoHopNeighborTuple tuple);
|
||||
void MprSelTupleTimerExpire (MprSelectorTuple tuple);
|
||||
void TopologyTupleTimerExpire (TopologyTuple tuple);
|
||||
void IfaceAssocTupleTimerExpire (IfaceAssocTuple tuple);
|
||||
|
||||
/// A list of pending messages which are buffered awaiting for being sent.
|
||||
std::vector<OlsrMessageHeader> m_queuedMessages;
|
||||
Timer m_queuedMessagesTimer; // timer for throttling outgoing messages
|
||||
|
||||
void ForwardDefault (OlsrMessageHeader olsrMessage,
|
||||
DuplicateTuple *duplicated,
|
||||
const Ipv4Address &localIface,
|
||||
const Ipv4Address &senderAddress);
|
||||
void QueueMessage (const OlsrMessageHeader &message, Time delay);
|
||||
void SendQueuedMessages ();
|
||||
void SendHello ();
|
||||
void SendTc ();
|
||||
void SendMid ();
|
||||
|
||||
void NeighborLoss (const LinkTuple &tuple);
|
||||
void AddDuplicateTuple (const DuplicateTuple &tuple);
|
||||
void RemoveDuplicateTuple (const DuplicateTuple &tuple);
|
||||
LinkTuple & AddLinkTuple (const LinkTuple &tuple, uint8_t willingness);
|
||||
void RemoveLinkTuple (const LinkTuple &tuple);
|
||||
void LinkTupleUpdated (const LinkTuple &tuple);
|
||||
void AddNeighborTuple (const NeighborTuple &tuple);
|
||||
void RemoveNeighborTuple (const NeighborTuple &tuple);
|
||||
void AddTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
|
||||
void RemoveTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
|
||||
void AddMprSelectorTuple (const MprSelectorTuple &tuple);
|
||||
void RemoveMprSelectorTuple (const MprSelectorTuple &tuple);
|
||||
void AddTopologyTuple (const TopologyTuple &tuple);
|
||||
void RemoveTopologyTuple (const TopologyTuple &tuple);
|
||||
void AddIfaceAssocTuple (const IfaceAssocTuple &tuple);
|
||||
void RemoveIfaceAssocTuple (const IfaceAssocTuple &tuple);
|
||||
|
||||
void ProcessHello (const OlsrMessageHeader &msg,
|
||||
const Ipv4Address &receiverIface,
|
||||
const Ipv4Address &senderIface);
|
||||
void ProcessTc (const OlsrMessageHeader &msg,
|
||||
const Ipv4Address &senderIface);
|
||||
void ProcessMid (const OlsrMessageHeader &msg,
|
||||
const Ipv4Address &senderIface);
|
||||
|
||||
void LinkSensing (const OlsrMessageHeader &msg,
|
||||
const OlsrMessageHeader::Hello &hello,
|
||||
const Ipv4Address &receiverIface,
|
||||
const Ipv4Address &sender_iface);
|
||||
void PopulateNeighborSet (const OlsrMessageHeader &msg,
|
||||
const OlsrMessageHeader::Hello &hello);
|
||||
void PopulateTwoHopNeighborSet (const OlsrMessageHeader &msg,
|
||||
const OlsrMessageHeader::Hello &hello);
|
||||
void PopulateMprSelectorSet (const OlsrMessageHeader &msg,
|
||||
const OlsrMessageHeader::Hello &hello);
|
||||
|
||||
int Degree (NeighborTuple const &tuple);
|
||||
|
||||
Ipv4Address m_mainAddress;
|
||||
Ptr<Socket> m_receiveSocket; // UDP socket for receving OSLR packets
|
||||
Ptr<Socket> m_sendSocket; // UDP socket for sending OSLR packets
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
29
src/routing/olsr/olsr-agent.cc
Normal file
29
src/routing/olsr/olsr-agent.cc
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
#include "olsr-agent.h"
|
||||
#include "olsr-agent-impl.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
const InterfaceId OlsrAgent::iid = MakeInterfaceId ("OlsrAgent", Object::iid);
|
||||
const ClassId OlsrAgent::cid = MakeClassId< OlsrAgentImpl, Ptr<Node> > ("OlsrAgent", OlsrAgent::iid);
|
||||
|
||||
}
|
||||
81
src/routing/olsr/olsr-agent.h
Normal file
81
src/routing/olsr/olsr-agent.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
#ifndef OLSR_AGENT_H
|
||||
#define OLSR_AGENT_H
|
||||
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/component-manager.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
/**
|
||||
* \brief Class implementing the OLSR state machine
|
||||
*
|
||||
* This class represents an instance of the OLSR protocol. It
|
||||
* attaches itself to a Node, and its lifecycle is bound to that node.
|
||||
* Normally the functions in the ns3::olsr namespace are more simple
|
||||
* to use to start OLSR on nodes, but access to the underlying OLSR
|
||||
* agent can be useful in order to customize the OLSR parameters.
|
||||
* Example:
|
||||
*
|
||||
* \code
|
||||
* Ptr<OlsrAgent> olsr = ComponentManager::Create<OlsrAgent, Ptr<Node> > (OlsrAgent::cid, OlsrAgent::iid, node);
|
||||
* agent->SetMainInterface (2);
|
||||
* agent->Start ();
|
||||
* \endcode
|
||||
*/
|
||||
class OlsrAgent : public Object
|
||||
{
|
||||
public:
|
||||
static const InterfaceId iid;
|
||||
static const ClassId cid;
|
||||
|
||||
/**
|
||||
* \brief Sets the main interface to be used by OLSR
|
||||
*
|
||||
* Normally OLSR supports multiple interfaces, but the protocol
|
||||
* requires the definition of a "main interface". This interface's
|
||||
* IPv4 address provides the identity of the node, and all outgoing
|
||||
* OLSR routing messages must have the main interface address,
|
||||
* regardless of the actual interface used to transmit the packet.
|
||||
* This method allows one to explicitly select an interface as the
|
||||
* main interface. It must be called before the agent starts, but
|
||||
* calling it is optional; if not called, the agent tries to guess
|
||||
* and uses a suitable interface.
|
||||
*/
|
||||
virtual void SetMainInterface (uint32_t interface) = 0;
|
||||
|
||||
/**
|
||||
* \brief Starts the OLSR protocol operation
|
||||
*
|
||||
* Calling this method essentially bootstraps the OLSR protocol, and
|
||||
* causes the agent to start broadcasting OLSR messages to
|
||||
* neighbors, as well start listening to messages from neighbors.
|
||||
*/
|
||||
virtual void Start () = 0;
|
||||
};
|
||||
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* OLSR_AGENT_H */
|
||||
|
||||
734
src/routing/olsr/olsr-header.cc
Normal file
734
src/routing/olsr/olsr-header.cc
Normal file
@@ -0,0 +1,734 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
#include "ns3/assert.h"
|
||||
|
||||
#include "olsr-header.h"
|
||||
|
||||
#define IPV4_ADDRESS_SIZE 4
|
||||
#define OLSR_MSG_HEADER_SIZE 12
|
||||
#define OLSR_PKT_HEADER_SIZE 4
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/// Scaling factor used in RFC 3626.
|
||||
#define OLSR_C 0.0625
|
||||
|
||||
///
|
||||
/// \brief Converts a decimal number of seconds to the mantissa/exponent format.
|
||||
///
|
||||
/// \param seconds decimal number of seconds we want to convert.
|
||||
/// \return the number of seconds in mantissa/exponent format.
|
||||
///
|
||||
uint8_t
|
||||
OlsrSecondsToEmf (double seconds)
|
||||
{
|
||||
int a, b = 0;
|
||||
|
||||
// find the largest integer 'b' such that: T/C >= 2^b
|
||||
for (b = 0; (seconds/OLSR_C) >= (1 << b); ++b)
|
||||
;
|
||||
NS_ASSERT ((seconds/OLSR_C) < (1 << b));
|
||||
b--;
|
||||
NS_ASSERT ((seconds/OLSR_C) >= (1 << b));
|
||||
|
||||
// compute the expression 16*(T/(C*(2^b))-1), which may not be a integer
|
||||
double tmp = 16*(seconds/(OLSR_C*(1<<b))-1);
|
||||
|
||||
// round it up. This results in the value for 'a'
|
||||
a = (int) ceil (tmp);
|
||||
|
||||
// if 'a' is equal to 16: increment 'b' by one, and set 'a' to 0
|
||||
if (a == 16)
|
||||
{
|
||||
b += 1;
|
||||
a = 0;
|
||||
}
|
||||
|
||||
// now, 'a' and 'b' should be integers between 0 and 15,
|
||||
NS_ASSERT (a >= 0 && a < 16);
|
||||
NS_ASSERT (b >= 0 && b < 16);
|
||||
|
||||
// the field will be a byte holding the value a*16+b
|
||||
return (uint8_t) ((a << 4) | b);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Converts a number of seconds in the mantissa/exponent format to a decimal number.
|
||||
///
|
||||
/// \param olsr_format number of seconds in mantissa/exponent format.
|
||||
/// \return the decimal number of seconds.
|
||||
///
|
||||
double
|
||||
OlsrEmfToSeconds (uint8_t olsrFormat)
|
||||
{
|
||||
int a = (olsrFormat >> 4);
|
||||
int b = (olsrFormat & 0xf);
|
||||
// value = C*(1+a/16)*2^b [in seconds]
|
||||
return OLSR_C * (1 + a/16.0) * (1 << b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------- OLSR Packet -------------------------------
|
||||
|
||||
OlsrPacketHeader::OlsrPacketHeader ()
|
||||
{}
|
||||
|
||||
OlsrPacketHeader::~OlsrPacketHeader ()
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
OlsrPacketHeader::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<OlsrPacketHeader>
|
||||
("OlsrPacketHeader.nsnam.org");
|
||||
return uid;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrPacketHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return OLSR_PKT_HEADER_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrPacketHeader::Print (std::ostream &os) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
OlsrPacketHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i.WriteHtonU16 (m_packetLength);
|
||||
i.WriteHtonU16 (m_packetSequenceNumber);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrPacketHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
m_packetLength = i.ReadNtohU16 ();
|
||||
m_packetSequenceNumber = i.ReadNtohU16 ();
|
||||
return GetSerializedSize ();
|
||||
}
|
||||
|
||||
|
||||
// ---------------- OLSR Message -------------------------------
|
||||
|
||||
OlsrMessageHeader::OlsrMessageHeader ()
|
||||
: m_messageType (OlsrMessageHeader::MessageType (0))
|
||||
{}
|
||||
|
||||
OlsrMessageHeader::~OlsrMessageHeader ()
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<OlsrMessageHeader>
|
||||
("OlsrMessageHeader.nsnam.org");
|
||||
return uid;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::GetSerializedSize (void) const
|
||||
{
|
||||
uint32_t size = OLSR_MSG_HEADER_SIZE;
|
||||
switch (m_messageType)
|
||||
{
|
||||
case MID_MESSAGE:
|
||||
size += m_message.mid.GetSerializedSize ();
|
||||
break;
|
||||
case HELLO_MESSAGE:
|
||||
size += m_message.hello.GetSerializedSize ();
|
||||
break;
|
||||
case TC_MESSAGE:
|
||||
size += m_message.tc.GetSerializedSize ();
|
||||
break;
|
||||
case HNA_MESSAGE:
|
||||
size += m_message.hna.GetSerializedSize ();
|
||||
break;
|
||||
default:
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Print (std::ostream &os) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
i.WriteU8 (m_messageType);
|
||||
i.WriteU8 (m_vTime);
|
||||
i.WriteHtonU16 (GetSerializedSize () - OLSR_MSG_HEADER_SIZE);
|
||||
i.WriteHtonU32 (m_originatorAddress.GetHostOrder ());
|
||||
i.WriteU8 (m_timeToLive);
|
||||
i.WriteU8 (m_hopCount);
|
||||
i.WriteHtonU16 (m_messageSequenceNumber);
|
||||
|
||||
switch (m_messageType)
|
||||
{
|
||||
case MID_MESSAGE:
|
||||
m_message.mid.Serialize (i);
|
||||
break;
|
||||
case HELLO_MESSAGE:
|
||||
m_message.hello.Serialize (i);
|
||||
break;
|
||||
case TC_MESSAGE:
|
||||
m_message.tc.Serialize (i);
|
||||
break;
|
||||
case HNA_MESSAGE:
|
||||
m_message.hna.Serialize (i);
|
||||
break;
|
||||
default:
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
uint32_t size;
|
||||
Buffer::Iterator i = start;
|
||||
m_messageType = (MessageType) i.ReadU8 ();
|
||||
NS_ASSERT (m_messageType >= HELLO_MESSAGE && m_messageType <= HNA_MESSAGE);
|
||||
m_vTime = i.ReadU8 ();
|
||||
m_messageSize = i.ReadNtohU16 ();
|
||||
m_originatorAddress = Ipv4Address (i.ReadNtohU32 ());
|
||||
m_timeToLive = i.ReadU8 ();
|
||||
m_hopCount = i.ReadU8 ();
|
||||
m_messageSequenceNumber = i.ReadNtohU16 ();
|
||||
size = OLSR_MSG_HEADER_SIZE;
|
||||
switch (m_messageType)
|
||||
{
|
||||
case MID_MESSAGE:
|
||||
size += m_message.mid.Deserialize (i, m_messageSize);
|
||||
break;
|
||||
case HELLO_MESSAGE:
|
||||
size += m_message.hello.Deserialize (i, m_messageSize);
|
||||
break;
|
||||
case TC_MESSAGE:
|
||||
size += m_message.tc.Deserialize (i, m_messageSize);
|
||||
break;
|
||||
case HNA_MESSAGE:
|
||||
size += m_message.hna.Deserialize (i, m_messageSize);
|
||||
break;
|
||||
default:
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
// ---------------- OLSR MID Message -------------------------------
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Mid::GetSerializedSize (void) const
|
||||
{
|
||||
return this->interfaceAddresses.size () * IPV4_ADDRESS_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Mid::Print (std::ostream &os) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Mid::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
for (std::vector<Ipv4Address>::const_iterator iter = this->interfaceAddresses.begin ();
|
||||
iter != this->interfaceAddresses.end (); iter++)
|
||||
{
|
||||
i.WriteHtonU32 (iter->GetHostOrder ());
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Mid::Deserialize (Buffer::Iterator start, uint32_t messageSize)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
this->interfaceAddresses.clear ();
|
||||
NS_ASSERT (messageSize >= 0);
|
||||
NS_ASSERT (messageSize % IPV4_ADDRESS_SIZE == 0);
|
||||
|
||||
int numAddresses = messageSize / IPV4_ADDRESS_SIZE;
|
||||
this->interfaceAddresses.erase (this->interfaceAddresses.begin(),
|
||||
this->interfaceAddresses.end ());
|
||||
for (int n = 0; n < numAddresses; ++n)
|
||||
this->interfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
|
||||
return GetSerializedSize ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------- OLSR HELLO Message -------------------------------
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Hello::GetSerializedSize (void) const
|
||||
{
|
||||
uint32_t size = 4;
|
||||
for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
|
||||
iter != this->linkMessages.end (); iter++)
|
||||
{
|
||||
const LinkMessage &lm = *iter;
|
||||
size += 4;
|
||||
size += IPV4_ADDRESS_SIZE * lm.neighborInterfaceAddresses.size ();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Hello::Print (std::ostream &os) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Hello::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
i.WriteU16 (0); // Reserved
|
||||
i.WriteU8 (this->hTime);
|
||||
i.WriteU8 (this->willingness);
|
||||
|
||||
for (std::vector<LinkMessage>::const_iterator iter = this->linkMessages.begin ();
|
||||
iter != this->linkMessages.end (); iter++)
|
||||
{
|
||||
const LinkMessage &lm = *iter;
|
||||
|
||||
i.WriteU8 (lm.linkCode);
|
||||
i.WriteU8 (0); // Reserved
|
||||
|
||||
// The size of the link message, counted in bytes and measured
|
||||
// from the beginning of the "Link Code" field and until the
|
||||
// next "Link Code" field (or - if there are no more link types
|
||||
// - the end of the message).
|
||||
i.WriteHtonU16 (4 + lm.neighborInterfaceAddresses.size () * IPV4_ADDRESS_SIZE);
|
||||
|
||||
for (std::vector<Ipv4Address>::const_iterator neigh_iter = lm.neighborInterfaceAddresses.begin ();
|
||||
neigh_iter != lm.neighborInterfaceAddresses.end (); neigh_iter++)
|
||||
{
|
||||
i.WriteHtonU32 (neigh_iter->GetHostOrder ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Hello::Deserialize (Buffer::Iterator start, uint32_t messageSize)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
NS_ASSERT (messageSize >= 4);
|
||||
|
||||
this->linkMessages.clear ();
|
||||
|
||||
uint16_t helloSizeLeft = messageSize;
|
||||
|
||||
i.ReadNtohU16 (); // Reserved
|
||||
this->hTime = i.ReadU8 ();
|
||||
this->willingness = i.ReadU8 ();
|
||||
|
||||
helloSizeLeft -= 4;
|
||||
|
||||
while (helloSizeLeft)
|
||||
{
|
||||
LinkMessage lm;
|
||||
NS_ASSERT (helloSizeLeft >= 4);
|
||||
lm.linkCode = i.ReadU8 ();
|
||||
i.ReadU8 (); // Reserved
|
||||
uint16_t lmSize = i.ReadNtohU16 ();
|
||||
NS_ASSERT ((lmSize - 4) % IPV4_ADDRESS_SIZE == 0);
|
||||
for (int n = (lmSize - 4) / IPV4_ADDRESS_SIZE; n; --n)
|
||||
{
|
||||
lm.neighborInterfaceAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
|
||||
}
|
||||
helloSizeLeft -= lmSize;
|
||||
this->linkMessages.push_back (lm);
|
||||
}
|
||||
|
||||
return messageSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------------- OLSR TC Message -------------------------------
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Tc::GetSerializedSize (void) const
|
||||
{
|
||||
return 4 + this->neighborAddresses.size () * IPV4_ADDRESS_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Tc::Print (std::ostream &os) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Tc::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
i.WriteHtonU16 (this->ansn);
|
||||
i.WriteHtonU16 (0); // Reserved
|
||||
|
||||
for (std::vector<Ipv4Address>::const_iterator iter = this->neighborAddresses.begin ();
|
||||
iter != this->neighborAddresses.end (); iter++)
|
||||
{
|
||||
i.WriteHtonU32 (iter->GetHostOrder ());
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Tc::Deserialize (Buffer::Iterator start, uint32_t messageSize)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
this->neighborAddresses.clear ();
|
||||
NS_ASSERT (messageSize >= 4);
|
||||
|
||||
this->ansn = i.ReadNtohU16 ();
|
||||
i.ReadNtohU16 (); // Reserved
|
||||
|
||||
NS_ASSERT ((messageSize - 4) % IPV4_ADDRESS_SIZE == 0);
|
||||
int numAddresses = (messageSize - 4) / IPV4_ADDRESS_SIZE;
|
||||
this->neighborAddresses.clear ();
|
||||
for (int n = 0; n < numAddresses; ++n)
|
||||
this->neighborAddresses.push_back (Ipv4Address (i.ReadNtohU32 ()));
|
||||
|
||||
return messageSize;
|
||||
}
|
||||
|
||||
|
||||
// ---------------- OLSR HNA Message -------------------------------
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Hna::GetSerializedSize (void) const
|
||||
{
|
||||
return 2*this->associations.size () * IPV4_ADDRESS_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Hna::Print (std::ostream &os) const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void
|
||||
OlsrMessageHeader::Hna::Serialize (Buffer::Iterator start) const
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
for (size_t n = 0; n < this->associations.size (); ++n)
|
||||
{
|
||||
i.WriteHtonU32 (this->associations[n].address.GetHostOrder ());
|
||||
i.WriteHtonU32 (this->associations[n].mask.GetHostOrder ());
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
OlsrMessageHeader::Hna::Deserialize (Buffer::Iterator start, uint32_t messageSize)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
NS_ASSERT (messageSize % (IPV4_ADDRESS_SIZE*2) == 0);
|
||||
int numAddresses = messageSize / IPV4_ADDRESS_SIZE / 2;
|
||||
this->associations.clear ();
|
||||
for (int n = 0; n < numAddresses; ++n)
|
||||
{
|
||||
Ipv4Address address (i.ReadNtohU32 ());
|
||||
Ipv4Mask mask (i.ReadNtohU32 ());
|
||||
this->associations.push_back ((Association) {address, mask});
|
||||
}
|
||||
return messageSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/packet.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class OlsrHeaderTest : public ns3::Test {
|
||||
private:
|
||||
public:
|
||||
OlsrHeaderTest ();
|
||||
virtual bool RunTests (void);
|
||||
|
||||
|
||||
};
|
||||
|
||||
OlsrHeaderTest::OlsrHeaderTest ()
|
||||
: ns3::Test ("OlsrHeader")
|
||||
{}
|
||||
|
||||
|
||||
bool
|
||||
OlsrHeaderTest::RunTests (void)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
// Testing packet header + message header + MID message
|
||||
{
|
||||
Packet packet;
|
||||
|
||||
{
|
||||
OlsrPacketHeader hdr;
|
||||
OlsrMessageHeader msg1;
|
||||
OlsrMessageHeader::Mid &mid1 = msg1.GetMid ();
|
||||
OlsrMessageHeader msg2;
|
||||
OlsrMessageHeader::Mid &mid2 = msg2.GetMid ();
|
||||
|
||||
// MID message #1
|
||||
{
|
||||
std::vector<Ipv4Address> &addresses = mid1.interfaceAddresses;
|
||||
addresses.clear ();
|
||||
addresses.push_back (Ipv4Address ("1.2.3.4"));
|
||||
addresses.push_back (Ipv4Address ("1.2.3.5"));
|
||||
}
|
||||
|
||||
msg1.SetTimeToLive (255);
|
||||
msg1.SetOriginatorAddress (Ipv4Address ("11.22.33.44"));
|
||||
msg1.SetVTime (Seconds (9));
|
||||
msg1.SetMessageSequenceNumber (7);
|
||||
|
||||
// MID message #2
|
||||
{
|
||||
std::vector<Ipv4Address> &addresses = mid2.interfaceAddresses;
|
||||
addresses.clear ();
|
||||
addresses.push_back (Ipv4Address ("2.2.3.4"));
|
||||
addresses.push_back (Ipv4Address ("2.2.3.5"));
|
||||
}
|
||||
|
||||
msg2.SetTimeToLive (254);
|
||||
msg2.SetOriginatorAddress (Ipv4Address ("12.22.33.44"));
|
||||
msg2.SetVTime (Seconds (10));
|
||||
msg2.SetMessageType (OlsrMessageHeader::MID_MESSAGE);
|
||||
msg2.SetMessageSequenceNumber (7);
|
||||
|
||||
// Build an OLSR packet header
|
||||
hdr.SetPacketLength (hdr.GetSerializedSize () + msg1.GetSerializedSize () + msg2.GetSerializedSize ());
|
||||
hdr.SetPacketSequenceNumber (123);
|
||||
|
||||
|
||||
// Now add all the headers in the correct order
|
||||
packet.AddHeader (msg2);
|
||||
packet.AddHeader (msg1);
|
||||
packet.AddHeader (hdr);
|
||||
}
|
||||
|
||||
{
|
||||
OlsrPacketHeader hdr;
|
||||
packet.RemoveHeader (hdr);
|
||||
NS_TEST_ASSERT_EQUAL (hdr.GetPacketSequenceNumber (), 123);
|
||||
uint32_t sizeLeft = hdr.GetPacketLength () - hdr.GetSerializedSize ();
|
||||
{
|
||||
OlsrMessageHeader msg1;
|
||||
|
||||
packet.RemoveHeader (msg1);
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (msg1.GetTimeToLive (), 255);
|
||||
NS_TEST_ASSERT_EQUAL (msg1.GetOriginatorAddress (), Ipv4Address ("11.22.33.44"));
|
||||
NS_TEST_ASSERT_EQUAL (msg1.GetVTime (), Seconds (9));
|
||||
NS_TEST_ASSERT_EQUAL (msg1.GetMessageType (), OlsrMessageHeader::MID_MESSAGE);
|
||||
NS_TEST_ASSERT_EQUAL (msg1.GetMessageSequenceNumber (), 7);
|
||||
|
||||
OlsrMessageHeader::Mid &mid1 = msg1.GetMid ();
|
||||
NS_TEST_ASSERT_EQUAL (mid1.interfaceAddresses.size (), 2);
|
||||
NS_TEST_ASSERT_EQUAL (*mid1.interfaceAddresses.begin (), Ipv4Address ("1.2.3.4"));
|
||||
|
||||
sizeLeft -= msg1.GetSerializedSize ();
|
||||
NS_TEST_ASSERT (sizeLeft > 0);
|
||||
}
|
||||
{
|
||||
// now read the second message
|
||||
OlsrMessageHeader msg2;
|
||||
|
||||
packet.RemoveHeader (msg2);
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (msg2.GetTimeToLive (), 254);
|
||||
NS_TEST_ASSERT_EQUAL (msg2.GetOriginatorAddress (), Ipv4Address ("12.22.33.44"));
|
||||
NS_TEST_ASSERT_EQUAL (msg2.GetVTime (), Seconds (10));
|
||||
NS_TEST_ASSERT_EQUAL (msg2.GetMessageType (), OlsrMessageHeader::MID_MESSAGE);
|
||||
NS_TEST_ASSERT_EQUAL (msg2.GetMessageSequenceNumber (), 7);
|
||||
|
||||
OlsrMessageHeader::Mid mid2 = msg2.GetMid ();
|
||||
NS_TEST_ASSERT_EQUAL (mid2.interfaceAddresses.size (), 2);
|
||||
NS_TEST_ASSERT_EQUAL (*mid2.interfaceAddresses.begin (), Ipv4Address ("2.2.3.4"));
|
||||
|
||||
sizeLeft -= msg2.GetSerializedSize ();
|
||||
NS_TEST_ASSERT_EQUAL (sizeLeft, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test the HELLO message
|
||||
{
|
||||
Packet packet;
|
||||
OlsrMessageHeader msgIn;
|
||||
OlsrMessageHeader::Hello &helloIn = msgIn.GetHello ();
|
||||
|
||||
helloIn.SetHTime (Seconds (7));
|
||||
helloIn.willingness = 66;
|
||||
|
||||
{
|
||||
OlsrMessageHeader::Hello::LinkMessage lm1;
|
||||
lm1.linkCode = 2;
|
||||
lm1.neighborInterfaceAddresses.push_back (Ipv4Address ("1.2.3.4"));
|
||||
lm1.neighborInterfaceAddresses.push_back (Ipv4Address ("1.2.3.5"));
|
||||
helloIn.linkMessages.push_back (lm1);
|
||||
|
||||
OlsrMessageHeader::Hello::LinkMessage lm2;
|
||||
lm2.linkCode = 3;
|
||||
lm2.neighborInterfaceAddresses.push_back (Ipv4Address ("2.2.3.4"));
|
||||
lm2.neighborInterfaceAddresses.push_back (Ipv4Address ("2.2.3.5"));
|
||||
helloIn.linkMessages.push_back (lm2);
|
||||
}
|
||||
|
||||
packet.AddHeader (msgIn);
|
||||
|
||||
OlsrMessageHeader msgOut;
|
||||
packet.RemoveHeader (msgOut);
|
||||
OlsrMessageHeader::Hello &helloOut = msgOut.GetHello ();
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.GetHTime (), Seconds (7));
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.willingness, 66);
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.linkMessages.size (), 2);
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[0].linkCode, 2);
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[0].neighborInterfaceAddresses[0],
|
||||
Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[0].neighborInterfaceAddresses[1],
|
||||
Ipv4Address ("1.2.3.5"));
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[1].linkCode, 3);
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[1].neighborInterfaceAddresses[0],
|
||||
Ipv4Address ("2.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (helloOut.linkMessages[1].neighborInterfaceAddresses[1],
|
||||
Ipv4Address ("2.2.3.5"));
|
||||
|
||||
// check that all bytes of the message were read
|
||||
NS_TEST_ASSERT_EQUAL (packet.GetSize (), 0);
|
||||
}
|
||||
|
||||
// Test the TC message
|
||||
{
|
||||
Packet packet;
|
||||
OlsrMessageHeader msgIn;
|
||||
OlsrMessageHeader::Tc &tcIn = msgIn.GetTc ();
|
||||
|
||||
tcIn.ansn = 0x1234;
|
||||
tcIn.neighborAddresses.push_back (Ipv4Address ("1.2.3.4"));
|
||||
tcIn.neighborAddresses.push_back (Ipv4Address ("1.2.3.5"));
|
||||
packet.AddHeader (msgIn);
|
||||
|
||||
OlsrMessageHeader msgOut;
|
||||
packet.RemoveHeader (msgOut);
|
||||
OlsrMessageHeader::Tc &tcOut = msgOut.GetTc ();
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (tcOut.ansn, 0x1234);
|
||||
NS_TEST_ASSERT_EQUAL (tcOut.neighborAddresses.size (), 2);
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (tcOut.neighborAddresses[0],
|
||||
Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (tcOut.neighborAddresses[1],
|
||||
Ipv4Address ("1.2.3.5"));
|
||||
|
||||
// check that all bytes of the message were read
|
||||
NS_TEST_ASSERT_EQUAL (packet.GetSize (), 0);
|
||||
}
|
||||
|
||||
// Test the HNA message
|
||||
{
|
||||
Packet packet;
|
||||
OlsrMessageHeader msgIn;
|
||||
OlsrMessageHeader::Hna &hnaIn = msgIn.GetHna ();
|
||||
|
||||
hnaIn.associations.push_back ((OlsrMessageHeader::Hna::Association)
|
||||
{ Ipv4Address ("1.2.3.4"), Ipv4Mask ("255.255.255.0")});
|
||||
hnaIn.associations.push_back ((OlsrMessageHeader::Hna::Association)
|
||||
{Ipv4Address ("1.2.3.5"), Ipv4Mask ("255.255.0.0")});
|
||||
packet.AddHeader (msgIn);
|
||||
|
||||
OlsrMessageHeader msgOut;
|
||||
packet.RemoveHeader (msgOut);
|
||||
OlsrMessageHeader::Hna &hnaOut = msgOut.GetHna ();
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (hnaOut.associations.size (), 2);
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (hnaOut.associations[0].address,
|
||||
Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (hnaOut.associations[0].mask,
|
||||
Ipv4Mask ("255.255.255.0"));
|
||||
|
||||
NS_TEST_ASSERT_EQUAL (hnaOut.associations[1].address,
|
||||
Ipv4Address ("1.2.3.5"));
|
||||
NS_TEST_ASSERT_EQUAL (hnaOut.associations[1].mask,
|
||||
Ipv4Mask ("255.255.0.0"));
|
||||
|
||||
// check that all bytes of the message were read
|
||||
NS_TEST_ASSERT_EQUAL (packet.GetSize (), 0);
|
||||
}
|
||||
|
||||
for (int time = 1; time <= 30; time++)
|
||||
{
|
||||
uint8_t emf = OlsrSecondsToEmf (time);
|
||||
double seconds = OlsrEmfToSeconds (emf);
|
||||
if (seconds < 0 || fabs (seconds - time) > 0.1)
|
||||
{
|
||||
result = false;
|
||||
Failure () << "In " << time << " out " << seconds << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static OlsrHeaderTest gOlsrHeaderTest;
|
||||
|
||||
}; // namespace
|
||||
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
440
src/routing/olsr/olsr-header.h
Normal file
440
src/routing/olsr/olsr-header.h
Normal file
@@ -0,0 +1,440 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
#ifndef OLSR_HEADER_H
|
||||
#define OLSR_HEADER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
#include "ns3/header.h"
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
double OlsrEmfToSeconds (uint8_t emf);
|
||||
uint8_t OlsrSecondsToEmf (double seconds);
|
||||
|
||||
// 3.3. Packet Format
|
||||
//
|
||||
// The basic layout of any packet in OLSR is as follows (omitting IP and
|
||||
// UDP headers):
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Packet Length | Packet Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Message Type | Vtime | Message Size |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Originator Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Time To Live | Hop Count | Message Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// : MESSAGE :
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Message Type | Vtime | Message Size |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Originator Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Time To Live | Hop Count | Message Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | |
|
||||
// : MESSAGE :
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// : :
|
||||
// (etc.)
|
||||
class OlsrPacketHeader : public Header
|
||||
{
|
||||
public:
|
||||
OlsrPacketHeader ();
|
||||
virtual ~OlsrPacketHeader ();
|
||||
|
||||
void SetPacketLength (uint16_t length)
|
||||
{
|
||||
m_packetLength = length;
|
||||
}
|
||||
uint16_t GetPacketLength () const
|
||||
{
|
||||
return m_packetLength;
|
||||
}
|
||||
|
||||
void SetPacketSequenceNumber (uint16_t seqnum)
|
||||
{
|
||||
m_packetSequenceNumber = seqnum;
|
||||
}
|
||||
uint16_t GetPacketSequenceNumber () const
|
||||
{
|
||||
return m_packetSequenceNumber;
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t m_packetLength;
|
||||
uint16_t m_packetSequenceNumber;
|
||||
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
virtual std::string GetName (void) const { return "OlsrPacket"; }
|
||||
};
|
||||
|
||||
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Message Type | Vtime | Message Size |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Originator Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Time To Live | Hop Count | Message Sequence Number |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
class OlsrMessageHeader : public Header
|
||||
{
|
||||
public:
|
||||
|
||||
enum MessageType {
|
||||
HELLO_MESSAGE = 1,
|
||||
TC_MESSAGE = 2,
|
||||
MID_MESSAGE = 3,
|
||||
HNA_MESSAGE = 4,
|
||||
};
|
||||
|
||||
OlsrMessageHeader ();
|
||||
virtual ~OlsrMessageHeader ();
|
||||
|
||||
void SetMessageType (MessageType messageType)
|
||||
{
|
||||
m_messageType = messageType;
|
||||
}
|
||||
MessageType GetMessageType () const
|
||||
{
|
||||
return m_messageType;
|
||||
}
|
||||
|
||||
void SetVTime (Time time)
|
||||
{
|
||||
m_vTime = OlsrSecondsToEmf (time.GetSeconds ());
|
||||
}
|
||||
Time GetVTime () const
|
||||
{
|
||||
return Seconds (OlsrEmfToSeconds (m_vTime));
|
||||
}
|
||||
|
||||
void SetOriginatorAddress (Ipv4Address originatorAddress)
|
||||
{
|
||||
m_originatorAddress = originatorAddress;
|
||||
}
|
||||
Ipv4Address GetOriginatorAddress () const
|
||||
{
|
||||
return m_originatorAddress;
|
||||
}
|
||||
|
||||
void SetTimeToLive (uint8_t timeToLive)
|
||||
{
|
||||
m_timeToLive = timeToLive;
|
||||
}
|
||||
uint8_t GetTimeToLive () const
|
||||
{
|
||||
return m_timeToLive;
|
||||
}
|
||||
|
||||
void SetHopCount (uint8_t hopCount)
|
||||
{
|
||||
m_hopCount = hopCount;
|
||||
}
|
||||
uint8_t GetHopCount () const
|
||||
{
|
||||
return m_hopCount;
|
||||
}
|
||||
|
||||
void SetMessageSequenceNumber (uint16_t messageSequenceNumber)
|
||||
{
|
||||
m_messageSequenceNumber = messageSequenceNumber;
|
||||
}
|
||||
uint16_t GetMessageSequenceNumber () const
|
||||
{
|
||||
return m_messageSequenceNumber;
|
||||
}
|
||||
|
||||
// void SetMessageSize (uint16_t messageSize)
|
||||
// {
|
||||
// m_messageSize = messageSize;
|
||||
// }
|
||||
// uint16_t GetMessageSize () const
|
||||
// {
|
||||
// return m_messageSize;
|
||||
// }
|
||||
|
||||
private:
|
||||
MessageType m_messageType;
|
||||
uint8_t m_vTime;
|
||||
Ipv4Address m_originatorAddress;
|
||||
uint8_t m_timeToLive;
|
||||
uint8_t m_hopCount;
|
||||
uint16_t m_messageSequenceNumber;
|
||||
uint16_t m_messageSize;
|
||||
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
virtual std::string GetName (void) const { return "OlsrMessage"; }
|
||||
|
||||
// 5.1. MID Message Format
|
||||
//
|
||||
// The proposed format of a MID message is as follows:
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | OLSR Interface Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | OLSR Interface Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | ... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
struct Mid
|
||||
{
|
||||
std::vector<Ipv4Address> interfaceAddresses;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize);
|
||||
};
|
||||
|
||||
// 6.1. HELLO Message Format
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
//
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Reserved | Htime | Willingness |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Link Code | Reserved | Link Message Size |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Neighbor Interface Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Neighbor Interface Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// : . . . :
|
||||
// : :
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Link Code | Reserved | Link Message Size |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Neighbor Interface Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Neighbor Interface Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// : :
|
||||
// : :
|
||||
// (etc.)
|
||||
struct Hello
|
||||
{
|
||||
struct LinkMessage {
|
||||
uint8_t linkCode;
|
||||
std::vector<Ipv4Address> neighborInterfaceAddresses;
|
||||
};
|
||||
|
||||
uint8_t hTime;
|
||||
void SetHTime (Time time)
|
||||
{
|
||||
this->hTime = OlsrSecondsToEmf (time.GetSeconds ());
|
||||
}
|
||||
Time GetHTime () const
|
||||
{
|
||||
return Seconds (OlsrEmfToSeconds (this->hTime));
|
||||
}
|
||||
|
||||
uint8_t willingness;
|
||||
std::vector<LinkMessage> linkMessages;
|
||||
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize);
|
||||
};
|
||||
|
||||
// 9.1. TC Message Format
|
||||
//
|
||||
// The proposed format of a TC message is as follows:
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | ANSN | Reserved |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Advertised Neighbor Main Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Advertised Neighbor Main Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | ... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
struct Tc
|
||||
{
|
||||
std::vector<Ipv4Address> neighborAddresses;
|
||||
uint16_t ansn;
|
||||
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize);
|
||||
};
|
||||
|
||||
|
||||
// 12.1. HNA Message Format
|
||||
//
|
||||
// The proposed format of an HNA-message is:
|
||||
//
|
||||
// 0 1 2 3
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Network Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Netmask |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Network Address |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Netmask |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | ... |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
// Note: HNA stands for Host Network Association
|
||||
struct Hna
|
||||
{
|
||||
struct Association
|
||||
{
|
||||
Ipv4Address address;
|
||||
Ipv4Mask mask;
|
||||
};
|
||||
std::vector<Association> associations;
|
||||
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start, uint32_t messageSize);
|
||||
};
|
||||
|
||||
private:
|
||||
struct
|
||||
{
|
||||
Mid mid;
|
||||
Hello hello;
|
||||
Tc tc;
|
||||
Hna hna;
|
||||
} m_message; // union not allowed
|
||||
|
||||
public:
|
||||
|
||||
Mid& GetMid ()
|
||||
{
|
||||
if (m_messageType == 0)
|
||||
{
|
||||
m_messageType = MID_MESSAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (m_messageType == MID_MESSAGE);
|
||||
}
|
||||
return m_message.mid;
|
||||
}
|
||||
|
||||
Hello& GetHello ()
|
||||
{
|
||||
if (m_messageType == 0)
|
||||
{
|
||||
m_messageType = HELLO_MESSAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (m_messageType == HELLO_MESSAGE);
|
||||
}
|
||||
return m_message.hello;
|
||||
}
|
||||
|
||||
Tc& GetTc ()
|
||||
{
|
||||
if (m_messageType == 0)
|
||||
{
|
||||
m_messageType = TC_MESSAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (m_messageType == TC_MESSAGE);
|
||||
}
|
||||
return m_message.tc;
|
||||
}
|
||||
|
||||
Hna& GetHna ()
|
||||
{
|
||||
if (m_messageType == 0)
|
||||
{
|
||||
m_messageType = HNA_MESSAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (m_messageType == HNA_MESSAGE);
|
||||
}
|
||||
return m_message.hna;
|
||||
}
|
||||
|
||||
|
||||
const Mid& GetMid () const
|
||||
{
|
||||
NS_ASSERT (m_messageType == MID_MESSAGE);
|
||||
return m_message.mid;
|
||||
}
|
||||
|
||||
const Hello& GetHello () const
|
||||
{
|
||||
NS_ASSERT (m_messageType == HELLO_MESSAGE);
|
||||
return m_message.hello;
|
||||
}
|
||||
|
||||
const Tc& GetTc () const
|
||||
{
|
||||
NS_ASSERT (m_messageType == TC_MESSAGE);
|
||||
return m_message.tc;
|
||||
}
|
||||
|
||||
const Hna& GetHna () const
|
||||
{
|
||||
NS_ASSERT (m_messageType == HNA_MESSAGE);
|
||||
return m_message.hna;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* OLSR_HEADER_H */
|
||||
|
||||
436
src/routing/olsr/olsr-state.cc
Normal file
436
src/routing/olsr/olsr-state.cc
Normal file
@@ -0,0 +1,436 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004 Francisco J. Ros
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Francisco J. Ros <fjrm@dif.um.es>
|
||||
* Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
///
|
||||
/// \file OlsrState.cc
|
||||
/// \brief Implementation of all functions needed for manipulating the internal
|
||||
/// state of an OLSR node.
|
||||
///
|
||||
|
||||
#include "olsr-state.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
/********** MPR Selector Set Manipulation **********/
|
||||
|
||||
MprSelectorTuple*
|
||||
OlsrState::FindMprSelectorTuple (Ipv4Address const &mainAddr)
|
||||
{
|
||||
for (MprSelectorSet::iterator it = m_mprSelectorSet.begin ();
|
||||
it != m_mprSelectorSet.end (); it++)
|
||||
{
|
||||
if (it->mainAddr == mainAddr)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseMprSelectorTuple (const MprSelectorTuple &tuple)
|
||||
{
|
||||
for (MprSelectorSet::iterator it = m_mprSelectorSet.begin ();
|
||||
it != m_mprSelectorSet.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_mprSelectorSet.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseMprSelectorTuples (const Ipv4Address &mainAddr)
|
||||
{
|
||||
for (MprSelectorSet::iterator it = m_mprSelectorSet.begin ();
|
||||
it != m_mprSelectorSet.end (); it++)
|
||||
{
|
||||
if (it->mainAddr == mainAddr)
|
||||
{
|
||||
it = m_mprSelectorSet.erase (it);
|
||||
it--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertMprSelectorTuple (MprSelectorTuple const &tuple)
|
||||
{
|
||||
m_mprSelectorSet.push_back (tuple);
|
||||
}
|
||||
|
||||
/********** Neighbor Set Manipulation **********/
|
||||
|
||||
NeighborTuple*
|
||||
OlsrState::FindNeighborTuple (Ipv4Address const &mainAddr)
|
||||
{
|
||||
for (NeighborSet::iterator it = m_neighborSet.begin ();
|
||||
it != m_neighborSet.end (); it++)
|
||||
{
|
||||
if (it->neighborMainAddr == mainAddr)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NeighborTuple*
|
||||
OlsrState::FindSymNeighborTuple (Ipv4Address const &mainAddr)
|
||||
{
|
||||
for (NeighborSet::iterator it = m_neighborSet.begin ();
|
||||
it != m_neighborSet.end (); it++)
|
||||
{
|
||||
if (it->neighborMainAddr == mainAddr && it->status == NeighborTuple::STATUS_SYM)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NeighborTuple*
|
||||
OlsrState::FindNeighborTuple (Ipv4Address const &mainAddr, uint8_t willingness)
|
||||
{
|
||||
for (NeighborSet::iterator it = m_neighborSet.begin ();
|
||||
it != m_neighborSet.end (); it++)
|
||||
{
|
||||
if (it->neighborMainAddr == mainAddr && it->willingness == willingness)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseNeighborTuple (const NeighborTuple &tuple)
|
||||
{
|
||||
for (NeighborSet::iterator it = m_neighborSet.begin ();
|
||||
it != m_neighborSet.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_neighborSet.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseNeighborTuple (const Ipv4Address &mainAddr)
|
||||
{
|
||||
for (NeighborSet::iterator it = m_neighborSet.begin ();
|
||||
it != m_neighborSet.end (); it++)
|
||||
{
|
||||
if (it->neighborMainAddr == mainAddr)
|
||||
{
|
||||
it = m_neighborSet.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertNeighborTuple (NeighborTuple const &tuple)
|
||||
{
|
||||
m_neighborSet.push_back (tuple);
|
||||
}
|
||||
|
||||
/********** Neighbor 2 Hop Set Manipulation **********/
|
||||
|
||||
TwoHopNeighborTuple*
|
||||
OlsrState::FindTwoHopNeighborTuple (Ipv4Address const &neighborMainAddr,
|
||||
Ipv4Address const &twoHopNeighborAddr)
|
||||
{
|
||||
for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
|
||||
it != m_twoHopNeighborSet.end (); it++)
|
||||
{
|
||||
if (it->neighborMainAddr == neighborMainAddr
|
||||
&& it->twoHopNeighborAddr == twoHopNeighborAddr)
|
||||
{
|
||||
return &(*it);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple)
|
||||
{
|
||||
for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
|
||||
it != m_twoHopNeighborSet.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_twoHopNeighborSet.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseTwoHopNeighborTuples (const Ipv4Address &neighborMainAddr,
|
||||
const Ipv4Address &twoHopNeighborAddr)
|
||||
{
|
||||
for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
|
||||
it != m_twoHopNeighborSet.end (); it++)
|
||||
{
|
||||
if (it->neighborMainAddr == neighborMainAddr
|
||||
&& it->twoHopNeighborAddr == twoHopNeighborAddr)
|
||||
{
|
||||
it = m_twoHopNeighborSet.erase (it);
|
||||
it--; // FIXME: is this correct in the case 'it' pointed to the first element?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseTwoHopNeighborTuples (const Ipv4Address &neighborMainAddr)
|
||||
{
|
||||
for (TwoHopNeighborSet::iterator it = m_twoHopNeighborSet.begin ();
|
||||
it != m_twoHopNeighborSet.end (); it++)
|
||||
{
|
||||
if (it->neighborMainAddr == neighborMainAddr) {
|
||||
it = m_twoHopNeighborSet.erase (it);
|
||||
it--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertTwoHopNeighborTuple (TwoHopNeighborTuple const &tuple){
|
||||
m_twoHopNeighborSet.push_back (tuple);
|
||||
}
|
||||
|
||||
/********** MPR Set Manipulation **********/
|
||||
|
||||
bool
|
||||
OlsrState::FindMprAddress (Ipv4Address const &addr)
|
||||
{
|
||||
MprSet::iterator it = m_mprSet.find (addr);
|
||||
return (it != m_mprSet.end ());
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertMprAddress (Ipv4Address const & addr)
|
||||
{
|
||||
m_mprSet.insert (addr);
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::ClearMprSet ()
|
||||
{
|
||||
m_mprSet.clear ();
|
||||
}
|
||||
|
||||
/********** Duplicate Set Manipulation **********/
|
||||
|
||||
DuplicateTuple*
|
||||
OlsrState::FindDuplicateTuple (Ipv4Address const &addr, uint16_t sequenceNumber)
|
||||
{
|
||||
for (DuplicateSet::iterator it = m_duplicateSet.begin ();
|
||||
it != m_duplicateSet.end(); it++)
|
||||
{
|
||||
if (it->address == addr && it->sequenceNumber == sequenceNumber)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseDuplicateTuple (const DuplicateTuple &tuple)
|
||||
{
|
||||
for (DuplicateSet::iterator it = m_duplicateSet.begin ();
|
||||
it != m_duplicateSet.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_duplicateSet.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertDuplicateTuple (DuplicateTuple const &tuple)
|
||||
{
|
||||
m_duplicateSet.push_back (tuple);
|
||||
}
|
||||
|
||||
/********** Link Set Manipulation **********/
|
||||
|
||||
LinkTuple*
|
||||
OlsrState::FindLinkTuple (Ipv4Address const & ifaceAddr)
|
||||
{
|
||||
for (LinkSet::iterator it = m_linkSet.begin ();
|
||||
it != m_linkSet.end (); it++)
|
||||
{
|
||||
if (it->neighborIfaceAddr == ifaceAddr)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LinkTuple*
|
||||
OlsrState::FindSymLinkTuple (Ipv4Address const &ifaceAddr, Time now)
|
||||
{
|
||||
for (LinkSet::iterator it = m_linkSet.begin ();
|
||||
it != m_linkSet.end (); it++)
|
||||
{
|
||||
if (it->neighborIfaceAddr == ifaceAddr)
|
||||
{
|
||||
if (it->symTime > now)
|
||||
return &(*it);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseLinkTuple (const LinkTuple &tuple)
|
||||
{
|
||||
for (LinkSet::iterator it = m_linkSet.begin ();
|
||||
it != m_linkSet.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_linkSet.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LinkTuple&
|
||||
OlsrState::InsertLinkTuple (LinkTuple const &tuple)
|
||||
{
|
||||
m_linkSet.push_back (tuple);
|
||||
return m_linkSet.back ();
|
||||
}
|
||||
|
||||
/********** Topology Set Manipulation **********/
|
||||
|
||||
TopologyTuple*
|
||||
OlsrState::FindTopologyTuple (Ipv4Address const &destAddr,
|
||||
Ipv4Address const &lastAddr)
|
||||
{
|
||||
for (TopologySet::iterator it = m_topologySet.begin ();
|
||||
it != m_topologySet.end (); it++)
|
||||
{
|
||||
if (it->destAddr == destAddr && it->lastAddr == lastAddr)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TopologyTuple*
|
||||
OlsrState::FindNewerTopologyTuple (Ipv4Address const & lastAddr, uint16_t ansn)
|
||||
{
|
||||
for (TopologySet::iterator it = m_topologySet.begin ();
|
||||
it != m_topologySet.end (); it++)
|
||||
{
|
||||
if (it->lastAddr == lastAddr && it->sequenceNumber > ansn)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseTopologyTuple(const TopologyTuple &tuple)
|
||||
{
|
||||
for (TopologySet::iterator it = m_topologySet.begin ();
|
||||
it != m_topologySet.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_topologySet.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseOlderTopologyTuples (const Ipv4Address &lastAddr, uint16_t ansn)
|
||||
{
|
||||
for (TopologySet::iterator it = m_topologySet.begin();
|
||||
it != m_topologySet.end(); it++)
|
||||
{
|
||||
if (it->lastAddr == lastAddr && it->sequenceNumber < ansn)
|
||||
{
|
||||
it = m_topologySet.erase (it);
|
||||
it--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertTopologyTuple (TopologyTuple const &tuple)
|
||||
{
|
||||
m_topologySet.push_back (tuple);
|
||||
}
|
||||
|
||||
/********** Interface Association Set Manipulation **********/
|
||||
|
||||
IfaceAssocTuple*
|
||||
OlsrState::FindIfaceAssocTuple (Ipv4Address const &ifaceAddr)
|
||||
{
|
||||
for (IfaceAssocSet::iterator it = m_ifaceAssocSet.begin ();
|
||||
it != m_ifaceAssocSet.end (); it++)
|
||||
{
|
||||
if (it->ifaceAddr == ifaceAddr)
|
||||
return &(*it);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::EraseIfaceAssocTuple (const IfaceAssocTuple &tuple)
|
||||
{
|
||||
for (IfaceAssocSet::iterator it = m_ifaceAssocSet.begin ();
|
||||
it != m_ifaceAssocSet.end (); it++)
|
||||
{
|
||||
if (*it == tuple)
|
||||
{
|
||||
m_ifaceAssocSet.erase (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OlsrState::InsertIfaceAssocTuple (const IfaceAssocTuple &tuple)
|
||||
{
|
||||
m_ifaceAssocSet.push_back (tuple);
|
||||
}
|
||||
|
||||
std::vector<Ipv4Address>
|
||||
OlsrState::FindNeighborInterfaces (const Ipv4Address &neighborMainAddr) const
|
||||
{
|
||||
std::vector<Ipv4Address> retval;
|
||||
for (IfaceAssocSet::const_iterator it = m_ifaceAssocSet.begin ();
|
||||
it != m_ifaceAssocSet.end (); it++)
|
||||
{
|
||||
if (it->mainAddr == neighborMainAddr)
|
||||
retval.push_back (it->ifaceAddr);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
144
src/routing/olsr/olsr-state.h
Normal file
144
src/routing/olsr/olsr-state.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004 Francisco J. Ros
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Francisco J. Ros <fjrm@dif.um.es>
|
||||
* Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
/// \brief This header file declares and defines internal state of an OLSR node.
|
||||
|
||||
#ifndef __OLSR_STATE_H__
|
||||
#define __OLSR_STATE_H__
|
||||
|
||||
#include "repositories.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
using namespace olsr;
|
||||
|
||||
/// This class encapsulates all data structures needed for maintaining internal state of an OLSR node.
|
||||
class OlsrState
|
||||
{
|
||||
// friend class Olsr;
|
||||
|
||||
protected:
|
||||
LinkSet m_linkSet; ///< Link Set (RFC 3626, section 4.2.1).
|
||||
NeighborSet m_neighborSet; ///< Neighbor Set (RFC 3626, section 4.3.1).
|
||||
TwoHopNeighborSet m_twoHopNeighborSet; ///< 2-hop Neighbor Set (RFC 3626, section 4.3.2).
|
||||
TopologySet m_topologySet; ///< Topology Set (RFC 3626, section 4.4).
|
||||
MprSet m_mprSet; ///< MPR Set (RFC 3626, section 4.3.3).
|
||||
MprSelectorSet m_mprSelectorSet; ///< MPR Selector Set (RFC 3626, section 4.3.4).
|
||||
DuplicateSet m_duplicateSet; ///< Duplicate Set (RFC 3626, section 3.4).
|
||||
IfaceAssocSet m_ifaceAssocSet; ///< Interface Association Set (RFC 3626, section 4.1).
|
||||
|
||||
public:
|
||||
|
||||
// MPR selector
|
||||
const MprSelectorSet & GetMprSelectors () const
|
||||
{
|
||||
return m_mprSelectorSet;
|
||||
}
|
||||
MprSelectorTuple* FindMprSelectorTuple (const Ipv4Address &mainAddr);
|
||||
void EraseMprSelectorTuple (const MprSelectorTuple &tuple);
|
||||
void EraseMprSelectorTuples (const Ipv4Address &mainAddr);
|
||||
void InsertMprSelectorTuple (const MprSelectorTuple &tuple);
|
||||
|
||||
// Neighbor
|
||||
const NeighborSet & GetNeighbors () const
|
||||
{
|
||||
return m_neighborSet;
|
||||
}
|
||||
NeighborTuple* FindNeighborTuple (const Ipv4Address &mainAddr);
|
||||
NeighborTuple* FindSymNeighborTuple (const Ipv4Address &mainAddr);
|
||||
NeighborTuple* FindNeighborTuple (const Ipv4Address &mainAddr,
|
||||
uint8_t willingness);
|
||||
void EraseNeighborTuple (const NeighborTuple &neighborTuple);
|
||||
void EraseNeighborTuple (const Ipv4Address &mainAddr);
|
||||
void InsertNeighborTuple (const NeighborTuple &tuple);
|
||||
|
||||
// Two-hop neighbor
|
||||
const TwoHopNeighborSet & GetTwoHopNeighbors () const
|
||||
{
|
||||
return m_twoHopNeighborSet;
|
||||
}
|
||||
TwoHopNeighborTuple* FindTwoHopNeighborTuple (const Ipv4Address &neighbor,
|
||||
const Ipv4Address &twoHopNeighbor);
|
||||
void EraseTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
|
||||
void EraseTwoHopNeighborTuples (const Ipv4Address &neighbor);
|
||||
void EraseTwoHopNeighborTuples (const Ipv4Address &neighbor,
|
||||
const Ipv4Address &twoHopNeighbor);
|
||||
void InsertTwoHopNeighborTuple (const TwoHopNeighborTuple &tuple);
|
||||
|
||||
// MPR
|
||||
bool FindMprAddress (const Ipv4Address &address);
|
||||
void InsertMprAddress (const Ipv4Address &address);
|
||||
void ClearMprSet ();
|
||||
|
||||
// Duplicate
|
||||
DuplicateTuple* FindDuplicateTuple (const Ipv4Address &address,
|
||||
uint16_t sequenceNumber);
|
||||
void EraseDuplicateTuple (const DuplicateTuple &tuple);
|
||||
void InsertDuplicateTuple (const DuplicateTuple &tuple);
|
||||
|
||||
// Link
|
||||
const LinkSet & GetLinks () const
|
||||
{
|
||||
return m_linkSet;
|
||||
}
|
||||
LinkTuple* FindLinkTuple (const Ipv4Address &ifaceAddr);
|
||||
LinkTuple* FindSymLinkTuple (const Ipv4Address &ifaceAddr, Time time);
|
||||
void EraseLinkTuple (const LinkTuple &tuple);
|
||||
LinkTuple& InsertLinkTuple (const LinkTuple &tuple);
|
||||
|
||||
// Topology
|
||||
const TopologySet & GetTopologySet () const
|
||||
{
|
||||
return m_topologySet;
|
||||
}
|
||||
TopologyTuple* FindTopologyTuple (const Ipv4Address &destAddr,
|
||||
const Ipv4Address &lastAddr);
|
||||
TopologyTuple* FindNewerTopologyTuple (const Ipv4Address &lastAddr,
|
||||
uint16_t ansn);
|
||||
void EraseTopologyTuple (const TopologyTuple &tuple);
|
||||
void EraseOlderTopologyTuples (const Ipv4Address &lastAddr,
|
||||
uint16_t ansn);
|
||||
void InsertTopologyTuple (const TopologyTuple &tuple);
|
||||
|
||||
// Interface association
|
||||
const IfaceAssocSet & GetIfaceAssocSet () const
|
||||
{
|
||||
return m_ifaceAssocSet;
|
||||
}
|
||||
IfaceAssocSet & GetIfaceAssocSetMutable ()
|
||||
{
|
||||
return m_ifaceAssocSet;
|
||||
}
|
||||
IfaceAssocTuple* FindIfaceAssocTuple (const Ipv4Address &ifaceAddr);
|
||||
void EraseIfaceAssocTuple (const IfaceAssocTuple &tuple);
|
||||
void InsertIfaceAssocTuple (const IfaceAssocTuple &tuple);
|
||||
|
||||
// Returns a vector of all interfaces of a given neighbor, with the
|
||||
// exception of the "main" one.
|
||||
std::vector<Ipv4Address>
|
||||
FindNeighborInterfaces (const Ipv4Address &neighborMainAddr) const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
42
src/routing/olsr/olsr.cc
Normal file
42
src/routing/olsr/olsr.cc
Normal file
@@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
#include "olsr-agent.h"
|
||||
#include "olsr.h"
|
||||
|
||||
namespace ns3 { namespace olsr {
|
||||
|
||||
|
||||
void
|
||||
EnableAllNodes (void)
|
||||
{
|
||||
EnableNodes <NodeList::Iterator> (NodeList::Begin (), NodeList::End ());
|
||||
}
|
||||
|
||||
void
|
||||
EnableNode (Ptr<Node> node)
|
||||
{
|
||||
ComponentManager::Create<OlsrAgent, Ptr<Node> >
|
||||
(OlsrAgent::cid, OlsrAgent::iid, node)->Start ();
|
||||
}
|
||||
|
||||
|
||||
}} // namespace ns3, olsr
|
||||
|
||||
66
src/routing/olsr/olsr.h
Normal file
66
src/routing/olsr/olsr.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
#ifndef OLSR_H
|
||||
#define OLSR_H
|
||||
|
||||
#include "ns3/node-list.h"
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
/**
|
||||
* \namespace ns3::olsr
|
||||
* \brief Includes a set of utility functions to enable OLSR on
|
||||
* certain nodes with default parameters. For finer grained control
|
||||
* of OLSR parameters, see OlsrAgent.
|
||||
*/
|
||||
namespace olsr
|
||||
{
|
||||
/// \brief Start the OLSR routing agent on all nodes
|
||||
void EnableAllNodes (void);
|
||||
|
||||
/// \brief Start the OLSR routing agent on a given list of nodes
|
||||
template <typename InputIterator>
|
||||
void EnableNodes (InputIterator begin, InputIterator end);
|
||||
|
||||
/// \brief Start the OLSR routing agent on the given node
|
||||
void EnableNode (Ptr<Node> node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// implementation
|
||||
namespace ns3
|
||||
{
|
||||
namespace olsr
|
||||
{
|
||||
template <typename InputIterator>
|
||||
void EnableNodes (InputIterator begin, InputIterator end)
|
||||
{
|
||||
for (InputIterator i = begin; i != end; i++)
|
||||
{
|
||||
EnableNode (*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* OLSR_H */
|
||||
198
src/routing/olsr/repositories.h
Normal file
198
src/routing/olsr/repositories.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004 Francisco J. Ros
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Francisco J. Ros <fjrm@dif.um.es>
|
||||
* Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
///
|
||||
/// \file OLSR_repositories.h
|
||||
/// \brief Here are defined all data structures needed by an OLSR node.
|
||||
///
|
||||
|
||||
#ifndef __OLSR_REPOSITORIES_H__
|
||||
#define __OLSR_REPOSITORIES_H__
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "ns3/ipv4-address.h"
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
namespace ns3 { namespace olsr {
|
||||
|
||||
|
||||
|
||||
/// An Interface Association Tuple.
|
||||
struct IfaceAssocTuple
|
||||
{
|
||||
/// Interface address of a node.
|
||||
Ipv4Address ifaceAddr;
|
||||
/// Main address of the node.
|
||||
Ipv4Address mainAddr;
|
||||
/// Time at which this tuple expires and must be removed.
|
||||
Time time;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
operator == (const IfaceAssocTuple &a, const IfaceAssocTuple &b)
|
||||
{
|
||||
return (a.ifaceAddr == b.ifaceAddr
|
||||
&& a.mainAddr == b.mainAddr);
|
||||
}
|
||||
|
||||
/// A Link Tuple.
|
||||
struct LinkTuple
|
||||
{
|
||||
/// Interface address of the local node.
|
||||
Ipv4Address localIfaceAddr;
|
||||
/// Interface address of the neighbor node.
|
||||
Ipv4Address neighborIfaceAddr;
|
||||
/// The link is considered bidirectional until this time.
|
||||
Time symTime;
|
||||
/// The link is considered unidirectional until this time.
|
||||
Time asymTime;
|
||||
/// The link is considered lost until this time (used for link layer notification).
|
||||
Time lostTime;
|
||||
/// Time at which this tuple expires and must be removed.
|
||||
Time time;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
operator == (const LinkTuple &a, const LinkTuple &b)
|
||||
{
|
||||
return (a.localIfaceAddr == b.localIfaceAddr
|
||||
&& a.neighborIfaceAddr == b.neighborIfaceAddr);
|
||||
}
|
||||
|
||||
/// A Neighbor Tuple.
|
||||
struct NeighborTuple
|
||||
{
|
||||
/// Main address of a neighbor node.
|
||||
Ipv4Address neighborMainAddr;
|
||||
/// Neighbor Type and Link Type at the four less significative digits.
|
||||
enum Status {
|
||||
STATUS_NOT_SYM = 0, // "not symmetric"
|
||||
STATUS_SYM = 1, // "symmetric"
|
||||
} status;
|
||||
/// A value between 0 and 7 specifying the node's willingness to carry traffic on behalf of other nodes.
|
||||
uint8_t willingness;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
operator == (const NeighborTuple &a, const NeighborTuple &b)
|
||||
{
|
||||
return (a.neighborMainAddr == b.neighborMainAddr
|
||||
&& a.status == b.status
|
||||
&& a.willingness == b.willingness);
|
||||
}
|
||||
|
||||
/// A 2-hop Tuple.
|
||||
struct TwoHopNeighborTuple
|
||||
{
|
||||
/// Main address of a neighbor.
|
||||
Ipv4Address neighborMainAddr;
|
||||
/// Main address of a 2-hop neighbor with a symmetric link to nb_main_addr.
|
||||
Ipv4Address twoHopNeighborAddr;
|
||||
/// Time at which this tuple expires and must be removed.
|
||||
Time expirationTime; // previously called 'time_'
|
||||
};
|
||||
|
||||
static inline bool
|
||||
operator == (const TwoHopNeighborTuple &a, const TwoHopNeighborTuple &b)
|
||||
{
|
||||
return (a.neighborMainAddr == b.neighborMainAddr
|
||||
&& a.twoHopNeighborAddr == b.twoHopNeighborAddr);
|
||||
}
|
||||
|
||||
/// An MPR-Selector Tuple.
|
||||
struct MprSelectorTuple
|
||||
{
|
||||
/// Main address of a node which have selected this node as a MPR.
|
||||
Ipv4Address mainAddr;
|
||||
/// Time at which this tuple expires and must be removed.
|
||||
Time expirationTime; // previously called 'time_'
|
||||
};
|
||||
|
||||
static inline bool
|
||||
operator == (const MprSelectorTuple &a, const MprSelectorTuple &b)
|
||||
{
|
||||
return (a.mainAddr == b.mainAddr);
|
||||
}
|
||||
|
||||
|
||||
/// The type "list of interface addresses"
|
||||
//typedef std::vector<nsaddr_t> addr_list_t;
|
||||
|
||||
/// A Duplicate Tuple
|
||||
struct DuplicateTuple
|
||||
{
|
||||
/// Originator address of the message.
|
||||
Ipv4Address address;
|
||||
/// Message sequence number.
|
||||
uint16_t sequenceNumber;
|
||||
/// Indicates whether the message has been retransmitted or not.
|
||||
bool retransmitted;
|
||||
/// List of interfaces which the message has been received on.
|
||||
std::vector<Ipv4Address> ifaceList;
|
||||
/// Time at which this tuple expires and must be removed.
|
||||
Time expirationTime;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
operator == (const DuplicateTuple &a, const DuplicateTuple &b)
|
||||
{
|
||||
return (a.address == b.address
|
||||
&& a.sequenceNumber == b.sequenceNumber);
|
||||
}
|
||||
|
||||
/// A Topology Tuple
|
||||
struct TopologyTuple
|
||||
{
|
||||
/// Main address of the destination.
|
||||
Ipv4Address destAddr;
|
||||
/// Main address of a node which is a neighbor of the destination.
|
||||
Ipv4Address lastAddr;
|
||||
/// Sequence number.
|
||||
uint16_t sequenceNumber;
|
||||
/// Time at which this tuple expires and must be removed.
|
||||
Time expirationTime;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
operator == (const TopologyTuple &a, const TopologyTuple &b)
|
||||
{
|
||||
return (a.destAddr == b.destAddr
|
||||
&& a.lastAddr == b.lastAddr
|
||||
&& a.sequenceNumber == b.sequenceNumber);
|
||||
}
|
||||
|
||||
|
||||
typedef std::set<Ipv4Address> MprSet; ///< MPR Set type.
|
||||
typedef std::vector<MprSelectorTuple> MprSelectorSet; ///< MPR Selector Set type.
|
||||
typedef std::vector<LinkTuple> LinkSet; ///< Link Set type.
|
||||
typedef std::vector<NeighborTuple> NeighborSet; ///< Neighbor Set type.
|
||||
typedef std::vector<TwoHopNeighborTuple> TwoHopNeighborSet; ///< 2-hop Neighbor Set type.
|
||||
typedef std::vector<TopologyTuple> TopologySet; ///< Topology Set type.
|
||||
typedef std::vector<DuplicateTuple> DuplicateSet; ///< Duplicate Set type.
|
||||
typedef std::vector<IfaceAssocTuple> IfaceAssocSet; ///< Interface Association Set type.
|
||||
|
||||
|
||||
}}; // namespace ns3, olsr
|
||||
|
||||
#endif /* __OLSR_REPOSITORIES_H__ */
|
||||
290
src/routing/olsr/routing-table.cc
Normal file
290
src/routing/olsr/routing-table.cc
Normal file
@@ -0,0 +1,290 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004 Francisco J. Ros
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Francisco J. Ros <fjrm@dif.um.es>
|
||||
* Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
///
|
||||
/// \file OLSR_rtable.cc
|
||||
/// \brief Implementation of our routing table.
|
||||
///
|
||||
|
||||
#include "routing-table.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/ipv4-header.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
namespace ns3 { namespace olsr {
|
||||
|
||||
NS_DEBUG_COMPONENT_DEFINE ("OlsrRoutingTable");
|
||||
|
||||
///
|
||||
/// \brief Clears the routing table and frees the memory assigned to each one of its entries.
|
||||
///
|
||||
void
|
||||
RoutingTable::Clear ()
|
||||
{
|
||||
m_table.clear ();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Deletes the entry whose destination address is given.
|
||||
/// \param dest address of the destination node.
|
||||
///
|
||||
void
|
||||
RoutingTable::RemoveEntry (Ipv4Address const &dest)
|
||||
{
|
||||
m_table.erase (dest);
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Looks up an entry for the specified destination address.
|
||||
/// \param dest destination address.
|
||||
/// \param outEntry output parameter to hold the routing entry result, if fuond
|
||||
/// \return true if found, false if not found
|
||||
///
|
||||
bool
|
||||
RoutingTable::Lookup (Ipv4Address const &dest,
|
||||
RoutingTableEntry &outEntry) const
|
||||
{
|
||||
// Get the iterator at "dest" position
|
||||
std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
|
||||
m_table.find (dest);
|
||||
// If there is no route to "dest", return NULL
|
||||
if (it == m_table.end ())
|
||||
return false;
|
||||
outEntry = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief Finds the appropiate entry which must be used in order to forward
|
||||
/// a data packet to a next hop (given a destination).
|
||||
///
|
||||
/// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the
|
||||
/// form [dest addr,next-hop addr]. In this case, if this function is invoked with
|
||||
/// [A,B] then pair [C,C] is returned because C is the next hop that must be used
|
||||
/// to forward a data packet destined to A. That is, C is a neighbor of this node,
|
||||
/// but B isn't. This function finds the appropiate neighbor for forwarding a packet.
|
||||
///
|
||||
/// \param entry the routing table entry which indicates the destination node
|
||||
/// we are interested in.
|
||||
/// \return the appropiate routing table entry which indicates the next
|
||||
/// hop which must be used for forwarding a data packet, or NULL
|
||||
/// if there is no such entry.
|
||||
///
|
||||
bool
|
||||
RoutingTable::FindSendEntry (RoutingTableEntry const &entry,
|
||||
RoutingTableEntry &outEntry) const
|
||||
{
|
||||
outEntry = entry;
|
||||
while (outEntry.destAddr != outEntry.nextAddr)
|
||||
{
|
||||
if (not Lookup(outEntry.nextAddr, outEntry))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RoutingTable::RequestRoute (uint32_t ifIndex,
|
||||
const Ipv4Header &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply)
|
||||
{
|
||||
RoutingTableEntry entry1, entry2;
|
||||
if (Lookup (ipHeader.GetDestination (), entry1))
|
||||
{
|
||||
bool foundSendEntry = FindSendEntry (entry1, entry2);
|
||||
if (!foundSendEntry)
|
||||
NS_FATAL_ERROR ("FindSendEntry failure");
|
||||
|
||||
Ipv4Route route = Ipv4Route::CreateHostRouteTo
|
||||
(ipHeader.GetDestination (), entry2.nextAddr, entry2.interface);
|
||||
|
||||
NS_DEBUG ("Olsr node" << m_mainAddress
|
||||
<< ": RouteRequest for dest=" << ipHeader.GetDestination ()
|
||||
<< " --> destHop=" << entry2.nextAddr
|
||||
<< " interface=" << entry2.interface);
|
||||
|
||||
routeReply (true, route, packet, ipHeader);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_DEBUG ("Olsr node" << m_mainAddress
|
||||
<< ": RouteRequest for dest=" << ipHeader.GetDestination ()
|
||||
<< " --> NOT FOUND");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RoutingTable::RequestIfIndex (Ipv4Address destination,
|
||||
uint32_t& ifIndex)
|
||||
{
|
||||
RoutingTableEntry entry1, entry2;
|
||||
if (Lookup (destination, entry1))
|
||||
{
|
||||
bool foundSendEntry = FindSendEntry (entry1, entry2);
|
||||
if (!foundSendEntry)
|
||||
NS_FATAL_ERROR ("FindSendEntry failure");
|
||||
ifIndex = entry2.interface;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// \brief Adds a new entry into the routing table.
|
||||
///
|
||||
/// If an entry for the given destination existed, it is deleted and freed.
|
||||
///
|
||||
/// \param dest address of the destination node.
|
||||
/// \param next address of the next hop node.
|
||||
/// \param iface address of the local interface.
|
||||
/// \param dist distance to the destination node.
|
||||
///
|
||||
void
|
||||
RoutingTable::AddEntry (Ipv4Address const &dest,
|
||||
Ipv4Address const &next,
|
||||
uint32_t interface,
|
||||
uint32_t distance)
|
||||
{
|
||||
// Creates a new rt entry with specified values
|
||||
RoutingTableEntry &entry = m_table[dest];
|
||||
|
||||
entry.destAddr = dest;
|
||||
entry.nextAddr = next;
|
||||
entry.interface = interface;
|
||||
entry.distance = distance;
|
||||
}
|
||||
|
||||
void
|
||||
RoutingTable::AddEntry (Ipv4Address const &dest,
|
||||
Ipv4Address const &next,
|
||||
Ipv4Address const &interfaceAddress,
|
||||
uint32_t distance)
|
||||
{
|
||||
RoutingTableEntry entry;
|
||||
NS_ASSERT (m_ipv4);
|
||||
for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
|
||||
{
|
||||
if (m_ipv4->GetAddress (i) == interfaceAddress)
|
||||
{
|
||||
AddEntry (dest, next, i, distance);
|
||||
return;
|
||||
}
|
||||
}
|
||||
NS_ASSERT (false); // should not be reached
|
||||
AddEntry (dest, next, 0, distance);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// \brief Returns the number of entries in the routing table.
|
||||
/// \return the number of entries in the routing table.
|
||||
///
|
||||
// u_int32_t
|
||||
// RoutingTable::size() {
|
||||
// return rt_.size();
|
||||
// }
|
||||
|
||||
}}; // namespace ns3, olsr
|
||||
|
||||
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
|
||||
#include "ns3/test.h"
|
||||
|
||||
|
||||
namespace ns3 { namespace olsr {
|
||||
|
||||
class OlsrRoutingTableTest : public ns3::Test {
|
||||
private:
|
||||
public:
|
||||
OlsrRoutingTableTest ();
|
||||
virtual bool RunTests (void);
|
||||
|
||||
|
||||
};
|
||||
|
||||
OlsrRoutingTableTest::OlsrRoutingTableTest ()
|
||||
: ns3::Test ("OlsrRoutingTable")
|
||||
{}
|
||||
|
||||
|
||||
bool
|
||||
OlsrRoutingTableTest::RunTests (void)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
RoutingTable table;
|
||||
|
||||
table.AddEntry (Ipv4Address ("1.2.3.5"),
|
||||
Ipv4Address ("1.2.3.4"),
|
||||
0,
|
||||
1);
|
||||
|
||||
table.AddEntry (Ipv4Address ("1.2.3.4"),
|
||||
Ipv4Address ("1.2.3.4"),
|
||||
0,
|
||||
1);
|
||||
|
||||
RoutingTableEntry entry1;
|
||||
NS_TEST_ASSERT (table.Lookup (Ipv4Address ("1.2.3.5"), entry1));
|
||||
NS_TEST_ASSERT_EQUAL (entry1.destAddr, Ipv4Address ("1.2.3.5"));
|
||||
NS_TEST_ASSERT_EQUAL (entry1.nextAddr, Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (entry1.interface, 0);
|
||||
NS_TEST_ASSERT_EQUAL (entry1.distance, 1);
|
||||
|
||||
RoutingTableEntry entry2;
|
||||
NS_TEST_ASSERT (table.Lookup (Ipv4Address ("1.2.3.4"), entry2));
|
||||
NS_TEST_ASSERT_EQUAL (entry2.destAddr, Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (entry2.nextAddr, Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (entry2.interface, 0);
|
||||
NS_TEST_ASSERT_EQUAL (entry2.distance, 1);
|
||||
|
||||
RoutingTableEntry sendEntry;
|
||||
NS_TEST_ASSERT (table.FindSendEntry (entry1, sendEntry));
|
||||
NS_TEST_ASSERT_EQUAL (sendEntry.destAddr, Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (sendEntry.nextAddr, Ipv4Address ("1.2.3.4"));
|
||||
NS_TEST_ASSERT_EQUAL (sendEntry.interface, 0);
|
||||
NS_TEST_ASSERT_EQUAL (sendEntry.distance, 1);
|
||||
|
||||
table.RemoveEntry (Ipv4Address ("1.2.3.5"));
|
||||
RoutingTableEntry removedEntry;
|
||||
NS_TEST_ASSERT (not table.Lookup (Ipv4Address ("1.2.3.5"), removedEntry));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static OlsrRoutingTableTest gOlsrRoutingTableTest;
|
||||
|
||||
}}; // namespace
|
||||
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
112
src/routing/olsr/routing-table.h
Normal file
112
src/routing/olsr/routing-table.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2004 Francisco J. Ros
|
||||
* Copyright (c) 2007 INESC Porto
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Francisco J. Ros <fjrm@dif.um.es>
|
||||
* Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
|
||||
*/
|
||||
|
||||
///
|
||||
/// \file OLSR_rtable.h
|
||||
/// \brief Header file for routing table's related stuff.
|
||||
///
|
||||
|
||||
#ifndef __OLSR_RTABLE_H__
|
||||
#define __OLSR_RTABLE_H__
|
||||
|
||||
#include "ns3/ipv4.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace ns3 { namespace olsr {
|
||||
|
||||
/// An %OLSR's routing table entry.
|
||||
struct RoutingTableEntry
|
||||
{
|
||||
Ipv4Address destAddr; ///< Address of the destination node.
|
||||
Ipv4Address nextAddr; ///< Address of the next hop.
|
||||
uint32_t interface; ///< Interface index
|
||||
uint32_t distance; ///< Distance in hops to the destination.
|
||||
|
||||
RoutingTableEntry () : // default values
|
||||
destAddr (), nextAddr (),
|
||||
interface (0), distance (0) {};
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Defines rtable_t as a map of OLSR_rt_entry, whose key is the destination address.
|
||||
///
|
||||
/// The routing table is thus defined as pairs: [dest address, entry]. Each element
|
||||
/// of the pair can be accesed via "first" and "second" members.
|
||||
///
|
||||
//typedef std::map<Ipv4Address, RoutingTableEntry> RoutingTable;
|
||||
|
||||
///
|
||||
/// \brief This class is a representation of the OLSR's Routing Table.
|
||||
///
|
||||
class RoutingTable : public Ipv4RoutingProtocol
|
||||
{
|
||||
std::map<Ipv4Address, RoutingTableEntry> m_table; ///< Data structure for the routing table.
|
||||
Ptr<Ipv4> m_ipv4;
|
||||
|
||||
Ipv4Address m_mainAddress; // used only for printing debug messages
|
||||
|
||||
void DoDispose ()
|
||||
{
|
||||
m_ipv4 = 0;
|
||||
Ipv4RoutingProtocol::DoDispose ();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
RoutingTable () {}
|
||||
RoutingTable (Ptr<Ipv4> ipv4, const Ipv4Address &mainAddress)
|
||||
:
|
||||
m_ipv4 (ipv4),
|
||||
m_mainAddress (mainAddress)
|
||||
{}
|
||||
|
||||
~RoutingTable () {}
|
||||
|
||||
void Clear ();
|
||||
void RemoveEntry (const Ipv4Address &dest);
|
||||
void AddEntry (const Ipv4Address &dest,
|
||||
const Ipv4Address &next,
|
||||
uint32_t interface,
|
||||
uint32_t distance);
|
||||
void AddEntry (const Ipv4Address &dest,
|
||||
const Ipv4Address &next,
|
||||
const Ipv4Address &interfaceAddress,
|
||||
uint32_t distance);
|
||||
bool Lookup (const Ipv4Address &dest,
|
||||
RoutingTableEntry &outEntry) const;
|
||||
bool FindSendEntry (const RoutingTableEntry &entry,
|
||||
RoutingTableEntry &outEntry) const;
|
||||
|
||||
// From Ipv4RoutingProtocol
|
||||
virtual bool RequestRoute (uint32_t ifIndex,
|
||||
const Ipv4Header &ipHeader,
|
||||
Packet packet,
|
||||
RouteReplyCallback routeReply);
|
||||
virtual bool RequestIfIndex (Ipv4Address destination,
|
||||
uint32_t& ifIndex);
|
||||
|
||||
};
|
||||
|
||||
}}; // namespace ns3, olsr
|
||||
|
||||
#endif
|
||||
21
src/routing/olsr/wscript
Normal file
21
src/routing/olsr/wscript
Normal file
@@ -0,0 +1,21 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
def build(bld):
|
||||
module = bld.create_ns3_module('olsr', ['internet-node'])
|
||||
module.includes = '.'
|
||||
module.source = [
|
||||
'olsr-header.cc',
|
||||
'olsr-state.cc',
|
||||
'routing-table.cc',
|
||||
'olsr-agent.cc',
|
||||
'olsr-agent-impl.cc',
|
||||
'olsr.cc',
|
||||
'event-garbage-collector.cc',
|
||||
]
|
||||
|
||||
headers = bld.create_obj('ns3header')
|
||||
headers.source = [
|
||||
'olsr-agent.h',
|
||||
'olsr.h',
|
||||
]
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "timer.h"
|
||||
#include "simulator.h"
|
||||
#include "simulation-singleton.h"
|
||||
#include "event-garbage-collector.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -31,16 +30,8 @@ Timer::Timer ()
|
||||
m_impl (0)
|
||||
{}
|
||||
|
||||
Timer::Timer (enum SchedulePolicy schedulePolicy,
|
||||
enum DestroyPolicy destroyPolicy)
|
||||
: m_flags (schedulePolicy | destroyPolicy),
|
||||
m_delay (FemtoSeconds (0)),
|
||||
m_event (),
|
||||
m_impl (0)
|
||||
{}
|
||||
|
||||
Timer::Timer (enum GarbageCollectPolicy policy)
|
||||
: m_flags (GARBAGE_COLLECT),
|
||||
Timer::Timer (enum DestroyPolicy destroyPolicy)
|
||||
: m_flags (destroyPolicy),
|
||||
m_delay (FemtoSeconds (0)),
|
||||
m_event (),
|
||||
m_impl (0)
|
||||
@@ -149,26 +140,11 @@ void
|
||||
Timer::Schedule (Time delay)
|
||||
{
|
||||
NS_ASSERT (m_impl != 0);
|
||||
if (m_flags & CHECK_ON_SCHEDULE)
|
||||
if (m_event.IsRunning ())
|
||||
{
|
||||
if (m_event.IsRunning ())
|
||||
{
|
||||
NS_FATAL_ERROR ("Event is still running while re-scheduling.");
|
||||
}
|
||||
}
|
||||
else if (m_flags & CANCEL_ON_SCHEDULE)
|
||||
{
|
||||
m_event.Cancel ();
|
||||
}
|
||||
else if (m_flags & REMOVE_ON_SCHEDULE)
|
||||
{
|
||||
Simulator::Remove (m_event);
|
||||
NS_FATAL_ERROR ("Event is still running while re-scheduling.");
|
||||
}
|
||||
m_event = m_impl->Schedule (delay);
|
||||
if (m_flags & GARBAGE_COLLECT)
|
||||
{
|
||||
SimulationSingleton<EventGarbageCollector>::Get ()->Track (m_event);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -43,23 +43,6 @@ class TimerImpl;
|
||||
class Timer
|
||||
{
|
||||
public:
|
||||
enum SchedulePolicy {
|
||||
/**
|
||||
* This policy cancels the event before scheduling a new event
|
||||
* for each call to Timer::Schedule.
|
||||
*/
|
||||
CANCEL_ON_SCHEDULE = (1<<0),
|
||||
/**
|
||||
* This policy removes the event from the simulation event list
|
||||
* before scheduling a new event for each call to Timer::Schedule.
|
||||
*/
|
||||
REMOVE_ON_SCHEDULE = (1<<1),
|
||||
/**
|
||||
* This policy enforces a check before each call to Timer::Schedule
|
||||
* to verify that the timer has already expired.
|
||||
*/
|
||||
CHECK_ON_SCHEDULE = (1<<2),
|
||||
};
|
||||
enum DestroyPolicy {
|
||||
/**
|
||||
* This policy cancels the event from the destructor of the Timer
|
||||
@@ -77,15 +60,6 @@ public:
|
||||
*/
|
||||
CHECK_ON_DESTROY = (1<<5)
|
||||
};
|
||||
enum GarbageCollectPolicy {
|
||||
/**
|
||||
* Every event scheduled with this policy is kept track of by an
|
||||
* event garbage collector which makes sure that all events
|
||||
* of timers with a GARBAGE_COLLECT policy are cancelled at the
|
||||
* end of the simulation.
|
||||
*/
|
||||
GARBAGE_COLLECT = (1<<6)
|
||||
};
|
||||
enum State {
|
||||
RUNNING,
|
||||
EXPIRED,
|
||||
@@ -93,21 +67,13 @@ public:
|
||||
};
|
||||
/**
|
||||
* create a timer with a default event lifetime management policy:
|
||||
* - CHECK_ON_SCHEDULE
|
||||
* - CHECK_ON_DESTROY
|
||||
*/
|
||||
Timer ();
|
||||
/**
|
||||
* \param scheduleFlags the event lifetime management policies to use for schedule events
|
||||
* \param destroyFlags the event lifetime management policies to use for destroy events
|
||||
*/
|
||||
Timer (enum SchedulePolicy schedulePolicy,
|
||||
enum DestroyPolicy destroyPolicy);
|
||||
/**
|
||||
* \param policy the garbage collect policy. Only one
|
||||
* value is possible.
|
||||
*/
|
||||
Timer (enum GarbageCollectPolicy policy);
|
||||
Timer (enum DestroyPolicy destroyPolicy);
|
||||
~Timer ();
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,7 +61,6 @@ def build(bld):
|
||||
'simulator.cc',
|
||||
'time-default-value.cc',
|
||||
'timer.cc',
|
||||
'event-garbage-collector.cc',
|
||||
'watchdog.cc',
|
||||
]
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ all_modules = (
|
||||
'applications/onoff',
|
||||
'applications/packet-sink',
|
||||
'applications/udp-echo',
|
||||
'routing/olsr',
|
||||
'routing/global-routing',
|
||||
'mobility',
|
||||
'devices/wifi',
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/debug.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("HelloSimulator");
|
||||
|
||||
@@ -23,7 +24,10 @@ using namespace ns3;
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
LogComponentEnable ("HelloSimulator", LOG_LEVEL_INFO);
|
||||
DebugComponentEnable ("Log");
|
||||
|
||||
// LogComponentEnable ("HelloSimulator",
|
||||
// LogLevel (LOG_LEVEL_INFO | LOG_PREFIX_ALL));
|
||||
|
||||
NS_LOG_INFO ("Hello Simulator");
|
||||
}
|
||||
|
||||
35
utils/bench-event-collector.cc
Normal file
35
utils/bench-event-collector.cc
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <stdlib.h>
|
||||
#include "ns3/event-collector.h"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
void Foo ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
EventCollector events;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
std::cerr << "usage: bench-event-collector NUM_EVENTS NUM_REPETITIONS" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
int numEvents = atoi (argv[1]);
|
||||
int numRepetitions = atoi (argv[2]);
|
||||
|
||||
for (int repetition = 0; repetition < numRepetitions; ++repetition)
|
||||
{
|
||||
for (int n = 0; n < numEvents; ++n)
|
||||
{
|
||||
events.Track (Simulator::Schedule (Simulator::Now (), Foo));
|
||||
}
|
||||
Simulator::Run ();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user