Category Archives: ns-2

Using TCP with ns-2

Having experimented a bit with TCP over MANETs in ns-2, I’ve made some learning points. I try to distillate these below.

Firstly, ns-2 has both one-way and two-way implementations of TCP to be employed. The two-way TCP only implements the Reno congestion avoidance algorithm, but on the other hand provides full establishment and tear-down procedures. The one-way TCP with a TCP sink as the destination can be used with several congestion avoidance implementations. Among these are Tahoe, Reno, Newreno, Vegas and Linux. I have experimented mostly with Tahoe, Reno and Newreno. Tahoe is the first implementation of TCP’s congestion control. The difference between Tahoe and Reno is that Reno implements fast retransmit and recovery upon receiving three duplicate ACKs. The difference between Reno and Newreno is that Newreno allows new retransmissions during the fast recovery phase, to keep the transmit window full.

TCP can be used by the FTP agent as follows:
set tcp(0) [new Agent/TCP/Newreno]
set sink(0) [new Agent/TCPSink]
set ftp(0) [new Application/FTP]
$sink(0) listen
$ns_ attach-agent $node_(0) $tcp(0)
$ns_ attach-agent $node_(1) $sink(0)
$ns_ connect $tcp(0) $sink(0)
$ftp(0) set packetSize_ 1024
$ftp(0) set random_ 1
$ftp(0) attach-agent $tcp(0)
$ns_ at $opt(ftpstart) "$ftp(0) start"

Note that the default receiver window is set at 20 packets, which can limit the throughput if the path has long transmission delay. The window can be set like this:
Agent/TCP set window_ 200 ;# max bound on window size
If flow control is unwanted, the window size can be set very high. However, if it is set too high, the default value of 20 will be used. Be aware!

Another discovery is that, using a propagation model with bit errors, link layer notification may render the recovery improvements of Reno and Newreno unused in case no other paths to the destination exist. When the link is taken down because of LLN, the (proactive) routing protocol must reestablish a symmetrical link. In the meantime, TCP retransmissions are denied because of a lack of route, with the consequence that fast recovery is botched.

Using ns-2 with Eclipse

Using Eclipse to debug ns-2 c++ code is very useful. Karthik Sankar has made a very good walkthrough for setting this up: http://blog.karthiksankar.com/ns2-eclipse/ However, I encountered some problems when following the walkthrough. Therefore, I repeat the walkthrough with the needed changes here. This solution should work with newer versions of ns-2 (i.e. 31-35) and Eclipse Indigo in Linux.

Setting up Eclipse:
Download Eclipse SDK
Extract the SDK to a folder
Open Eclipse
Go to Help -> Install New Software. In the Work With bar type this:

http://download.eclipse.org/tools/cdt/releases/galileo

Choose CDT Main Features and CDT Optional Features. Install them.
CDT stands for “C/C++ Development Tooling”
If you do not have a working internet connection in the system you have installed Eclipse, instead of steps 4 and 5, download the CDT from the above mentioned site. Then move to Install New Software (see step 4) -> Add and add the archive downloaded.

Installing NS-2:
Download NS-2
Extract NS-2 to a folder, i.e. /home/username/ns-allinone-2.34
Edit Makefile:
Open “…/ns-allinone-2.34/ns-2.34/Makefile.in” and
Add -g to the line CCOPT = @V_CCOPT@ as follows
CCOPT = @V_CCOPT@ -g
Add -DNDEBUG -DDEBUG to the end of the following line:
DEFINE = -DTCP_DELAY_BIND_ALL -DNO_TK @V_DEFINE@ @V_DEFINES@ @DEFS@-DNS_DIFFUSION -DSMAC_NO_SYNC -DCPP_NAMESPACE=@CPP_NAMESPACE@-DUSE_SINGLE_ADDRESS_SPACE -Drng_test -DNDEBUG -DDEBUG
Navigate to …/ns-allinone-2.34/ns-2.34 and run “./configure”
Navigate to the NS-2 folder using terminal and type ./install
Also, follow the instructions are displayed at the end of a successful installation. These instructions are to modify the PATH variable and other environment variables as needed.
You may encounter compilation troubles, due to the DEBUG flag being enabled. My experience was that several printf statements needed to be disabled (commented out):
mobile/shadowing-vis.cc line 293
aodv/aodv.cc line 210
aomdv/aomdv_rtable.cc line 186
aomdv/aomdv.cc line 283

Adding NS-2 as a Project in Eclipse:
Open Eclipse
Set the workspace as the ns installation path( /home/username/ns-allinone-2.34 ) by selecting File -> Switch Workspace
Choose File -> New -> Project -> C++ Project
Select Project Type as Makefile Project -> Empty C++ Project.
Toolchains: Linux GCC
Enter Project Name as ns-2.34
Uncheck “Use default location” then browse to the directory NS-2 source directory ( …/ns-allione-2.34/ns-2.34 )
In Eclipse Indigo, you may not be allowed to create a new project in the existing ns-2.34 subfolder if you uncheck the “Use default location” checkbox. You will not need to, anyway, if you have chosen the parent folder as workspace. In this case, Eclipse will only warn you that you are creating a project in a directory which already exists.
Select “Next” and “Finish”.
From the workspace, Selecting the NS-2 Project and choosing Project -> Build All should not give Error.
Running the project must open the console with the NS-2 prompt, %

Setting Debug Configuration:
Select Run -> Debug Configurations
Choose C/C++ Application. Type in any name.
Under the Main tab, Choose the following:
Project as ns-2.34.
C/C++ Application as ns. (Search Project and Choose this)
Under the Debugger tab, choose GDB Debugger. Uncheck the “Stop on startup at” option.
Apply and Debug.

Installing ns-2.34 on Ubuntu 11.10 Oneiric Ocelot

This is almost identical to the way ns-2.34 is installed on Ubuntu 11.04, except for the lines in bold face:

Install the development files for X Windows plus the g++ compiler:
sudo apt-get install xorg-dev g++ xgraph

Fix the error in the linking of otcl by editing line 6304 of otcl-1.13/configure so that it reads
SHLIB_LD="gcc -shared"
instead of
SHLIB_LD="ld -shared"

Then, edit the file ns-2.34/tools/ranvar.cc and change the line 219 from
return GammaRandomVariable::GammaRandomVariable(1.0 + alpha_, beta_).value() * pow (u, 1.0 / alpha_);
to
return GammaRandomVariable(1.0 + alpha_, beta_).value() * pow (u, 1.0 / alpha_);

Next, change the lines 183 and 185 in file ns-2.34/mobile/nakagami.cc to read
resultPower = ErlangRandomVariable(Pr/m, int_m).value();
and
resultPower = GammaRandomVariable(m, Pr/m).value();

Add a line after line 64 in ns-2.34/mac/mac-802_11Ext.h to read:
#include <stddef.h>

Now the code will compile if you run ./install. However, you may not be able to run the ns executable. If you get an error stating that there has been a buffer overflow *** buffer overflow detected ***: ./ns terminated including a backtrace, you need to do the following to make it work:

Install gcc-4.4 and g++-4.4 including dependencies using the code below:
$ sudo apt-get install gcc-4.4 g++-4.4

Change the line 270 in tcl8.4.18/unix/Makefile.in that reads
CC = @CC@
so it uses gcc version 4.4:
CC = gcc-4.4

Finally, run ./install from the ns-allinone-2.34 top folder again.

P.S. If you are moving and renaming ns-2 folders as time goes by, check the tip here on a potential problem with tk.

Installing ns-2.34 on Ubuntu 11.04

First, do the same things as you would do for the ns-2.34 and Ubuntu 10.10 installation, i.e.:

Install the development files for X Windows plus the g++ compiler:
sudo apt-get install xorg-dev g++ xgraph

Fix the error in the linking of otcl by editing line 6304 of otcl-1.13/configure so that it reads
SHLIB_LD="gcc -shared"
instead of
SHLIB_LD="ld -shared"

Then, edit the file ns-2.34/tools/ranvar.cc and change the line 219 from
return GammaRandomVariable::GammaRandomVariable(1.0 + alpha_, beta_).value() * pow (u, 1.0 / alpha_);
to
return GammaRandomVariable(1.0 + alpha_, beta_).value() * pow (u, 1.0 / alpha_);

Next, change the lines 183 and 185 in file ns-2.34/mobile/nakagami.cc to read
resultPower = ErlangRandomVariable(Pr/m, int_m).value();
and
resultPower = GammaRandomVariable(m, Pr/m).value();

Now the code will compile if you run ./install. However, you may not be able to run the ns executable. If you get an error stating that there has been a buffer overflow *** buffer overflow detected ***: ./ns terminated including a backtrace, you need to do the following to make it work:

Install gcc-4.4 and g++-4.4 including dependencies using the code below:
$ sudo apt-get install gcc-4.4 g++-4.4

Change the line 270 in tcl8.4.18/unix/Makefile.in that reads
CC = @CC@
so it appends the version parameter for version 4.4:
CC = @CC@ -V 4.4
Make sure it is a capital V.

Finally, run ./install from the ns-allinone-2.34 top folder again.

See also: Installing ns-2.34 on Ubuntu 11.10 Oneiric Ocelot

Disabling ARP in ns-2.34

For some purposes, disabling ARP may be desired, in order to study network properties in the ns-2 simulator. In ns-2, the MAC and IP addresses are the same, making ARP disabling very easy. To disable the ARP protocol in ns-2.34, add these lines to the top of ARPTable::arpresolve in the file mac/arp.cc:

hdr_cmn *ch = HDR_CMN(p);
mac_->hdr_dst((char*) HDR_MAC(p), ch->next_hop());
return 0;

Referred from a mail exchange between Ahmad Khayyat and Pedro Vale Estrela.

Installing ns-2.34 on Ubuntu 10.10

To keep up the pace with new versions of Ubuntu and potentially new installation problems with ns-2, here is a recipe for installing ns-2.34 on Ubuntu 10.10:

Download and extract ns-2.34 to a folder in your home directory. Get ns-2.34 allinone here.

Install the development files for X Windows plus the g++ compiler:
sudo apt-get install xorg-dev g++ xgraph

Fix the error in the linking of otcl by editing line 6304 of otcl-1.13/configure so that it reads
SHLIB_LD="gcc -shared"
instead of
SHLIB_LD="ld -shared"

And run ./install

Good luck!

See also: Installing ns-2.34 on Ubuntu 11.10 Oneiric Ocelot

Implementing Ingress Queuing for OLSR in ns-2

This walkthrough is for implementing Ingress Queuing for OLSR in ns-2. The OLSR version is as implemented by the University of Murcia. Ingress Queuing is presented by Lars Landmark, Knut Øvsthus and Øivind Kure in “Alternative packet forwarding for otherwise discarded packets”, FGCN2007, and the walkthrough is based on ns-2.34.

In principle, Ingress Queuing is the possibility to route packets immediately before handing them to the network card, meaning AFTER the packets have been queued in the interface queue. All that is required is for the MAC-layer code to request a routing operation from the routing protocol as the packet is fetched from the interface queue to be transmitted. The benefit of such a mechanism is that possible route changes that are discovered by the routing protocol after a packet has been committed to the interface queue with a routed link layer next hop address can be used to increase the probability of transmission success.

Changes are required to:
– the script file, where the routing protocol handle must be sent to the mac protocol.
– the routing protocol’s main file and header file, to deliver the handle to the mac protocol.
– the mac protocol’s main file and header file, to receive the handle from the routing protocol and to do the extra routing operation.

Changes to the script file:
The initialization of all nodes in the network must be appended with the passing of a routing protocol handle to the mac protocol.

for {set i 0} {$i < $opt(nn) } {incr i} {
set node_($i) [$ns_ node]
$node_($i) random-motion 0 ;# disable random motion
puts "Routing access from mac for node $i: "
set nmac_($i) [$node_($i) set mac_(0)]
set nolsr_($i) [$node_($i) agent 255]
$nmac_($i) register-olsr $nolsr_($i)
}

Changes to the OLSR code in OLSR.cc to enable the mac layer to check up the newest next hop:


nsaddr_t OLSR::lookup(nsaddr_t a)
{
OLSR_rt_entry* entry = rtable_.lookup(a);

if (entry == NULL) {
return -1;
}
else {
entry = rtable_.find_send_entry(entry);
assert(entry != NULL);
return entry->next_addr();
}
return -1;
}

Changes to OLSR.h:


nsaddr_t lookup(nsaddr_t);

Changes to mac-802_11.h:
#include "olsr/OLSR.h"
And under private variables:
OLSR* olsr_;
int ingress_;

Changes to mac-802_11.cc:
At the top, right after the includes:

#define IP_MULTICAST 0xE000000

Inside the construct, at the end:
bind_bool("ingress", &ingress_);
Inside the int Mac802_11::command(int argc, const char*const* argv) function right before the end of the if (argc == 3):

else if(strcmp(argv[1], "register-olsr") == 0 ){
olsr_ = (OLSR*)TclObject::lookup(argv[2]);
printf("Registering olsr: %s\n",argv[2]);
return TCL_OK;
}

In addition in function void Mac802_11::recv(Packet *p, Handler *h) right after the line if(hdr->direction() == hdr_cmn::DOWN) {:

if (hdr->ptype() != PT_OLSR && hdr->addr_type() == NS_AF_INET)
{
if (ingress_ == true){
struct hdr_ip *ih = HDR_IP(p);
nsaddr_t nexthop = olsr_->lookup(ih->daddr());
nsaddr_t oldhop = hdr->next_hop();
if (nexthop != -1){
if (hdr->next_hop() != nexthop){
if (ih->daddr() == nexthop)
//printf("(%f) %d from %d to %d, next hop now %d, not %d.\n",now,hdr->uid(),index_,ih->daddr(),nexthop,hdr->next_hop() );

hdr->next_hop_ = olsr_->lookup(ih->daddr());
struct hdr_mac* dh = HDR_MAC(p);
char *mh = (char*)HDR_MAC(p);
dh->macDA() = nexthop;
hdr_dst(mh, nexthop);
//printf("changed from %d to %d\n",oldhop,hdr->next_hop());
}
}
else if (ih->daddr() handle((Event*) 0);
return;
}
}
}

ns-3.9 in Ubuntu 10.10

This will be a post expanding as new knowledge is gained. I am in the process of installing ns-3.9 on a version of Ubuntu 10.10 already running ns-2.34, and with a Python run-time module installed, so this is not a post covering all potential errors that users installing on a clean version of Ubuntu may encounter.

First, after downloading the ns-allinone-3.9 code, the build process is started with build.py. If an error such as the one below occurs:
In file included from debug/bindings/python/ns3module.cc:1:
debug/bindings/python/pch/ns3module.h:3:20: error: Python.h: No such file or directory

install the Python development kit:
sudo apt-get install python-dev
Taken from here.

Changing the OLSR HELLO and TC intervals

When changing the HELLO and TC intervals in the ns-2 OLSR implementation by Ros and Ruiz (v0.8.8), we use the definitions in the script file, for example:

Agent/OLSR set hello_ival_ 2.0
Agent/OLSR set tc_ival_ 5.0

However, bugs have found their way into the code, so you have to make the following changes in olsr.h to make it behave properly:

  • Change the hello_ival_ and tc_ival_ from int to double, and the corresponding functions accordingly.
  • Change the macro definitions for OLSR_HELLO_INTERVAL, OLSR_TC_INTERVAL, OLSR_MID_INTERVAL and OLSR_REFRESH_INTERVAL from 2 and 5 to hello_ival_ and tc_ival_ respectively.

Running TORA in ns-2.34 on Ubuntu 10.04

First, patch the ns-2.34 code using the patch and recipe from http://wpage.unina.it/marcello.caleffi/ns2/tora.html.

Then, to avoid eternal loops making the simulation never ending, fix the line 504 (ns-2.34) in imep/imep.cc which reads

rexmitTimer.start(rexat - CURRENT_TIME);

If rexat – CURRENT_TIME is 0, then the same function is called immediately without increasing the simulation time, creating an eternal loop. I would have replaced the line with the following lines:

if (rexat-CURRENT_TIME<0.000001) // Preventing eternal loop.
   rexmitTimer.start(0.000001);
else
   rexmitTimer.start(rexat - CURRENT_TIME);

Then recompile with make, and enjoy. :-)