Mar 3, 2006

How do add a new module in NS-2

Got this translated from a chinese website (link).

** Based on cygwin and Ns-2 2.27

To add a module in Ns-2 is not a simple task especially for beginner. Therefore it's the author's wish to assist beginner by writing this article. However, the author would like to remind that there are plenty of modules that already existing in Ns-2. By merely editing the exiting module and adding extra functions, it's sufficient to be the first step to add a new module in Ns=2.

Step 1

Open cygwin command window, and change directory to the following path
cd ns-allinone-2.27/ns-2.27/queue

Step 2

Change the name of drop-tail.[cc, h] to myfifo.[cc, h]
cp drop-tail.cc myfifo.cc
cp drop-tail.h myfifo.h

Step 3

By using editor, edit myfifo.h and myfifo.c (if you are in windows environment, you may use software like Ultra-edit to edit)

a. Firstly, edit myfifo.h by changing everything from Droptail to myfifo and drop_tail to myfifo

#ifndef ns_myfifo_h
#define ns_myfifo_h

#include
#include "queue.h"
#include "config.h"

/*
* A bounded, drop-tail queue
*/

class myfifo : public Queue {
public:
myfifo() {
q_ = new PacketQueue;
pq_ = q_;
bind_bool("drop_front_", &drop_front_);
bind_bool("summarystats_", &summarystats);
bind_bool("queue_in_bytes_", &qib_); // boolean: q in bytes?
bind("mean_pktsize_", &mean_pktsize_);
// _RENAMED("drop-front_", "drop_front_");
}
~myfifo() {
delete q_;
}
protected:
void reset();
int command(int argc, const char*const* argv);
void enque(Packet*);
Packet* deque();
void shrink_queue(); // To shrink queue and drop excessive packets.
PacketQueue *q_; /* underlying FIFO queue */
int drop_front_; /* drop-from-front (rather than from tail) */
int summarystats;
void print_summarystats();
int qib_; /* bool: queue measured in bytes? */
int mean_pktsize_; /* configured mean packet size in bytes */
};

#endif

b. next is to edit myfifo.cc, change everything from DropTail to myfifo and everything from drop_tail to myfifo and drop-tail to myfifo

#include "myfifo.h"

static class myfifoClass : public TclClass {
public:
myfifoClass() : TclClass("Queue/myfifo") {}
TclObject* create(int, const char*const*) {
return (new myfifo);
}
} class_myfifo;

void myfifo::reset()
{
Queue::reset();
}
int myfifo::command(int argc, const char*const* argv) {
if (argc==2) {
if (strcmp(argv[1], "printstats") == 0) {
print_summarystats();
return (TCL_OK);
}
if (strcmp(argv[1], "shrink-queue") == 0) {
shrink_queue();
return (TCL_OK);
}
}

if (argc == 3) {
if (!strcmp(argv[1], "packetqueue-attach")) {
delete q_;
if (!(q_ = (PacketQueue*) TclObject::lookup(argv[2])))
return (TCL_ERROR);
else {
pq_ = q_;
return (TCL_OK);
}
}
}
return Queue::command(argc, argv);
}

/*
* drop-tail
*/

void myfifo::enque(Packet* p)
{
if (summarystats) {
Queue::updateStats(qib_?q_->byteLength():q_->length());
}
int qlimBytes = qlim_ * mean_pktsize_;
if ((!qib_ && (q_->length() + 1) >= qlim_) ||
(qib_ && (q_->byteLength() + hdr_cmn::access(p)->size()) >= qlimBytes)){
// if the queue would overflow if we added this packet...
if (drop_front_) { /* remove from head of queue */
q_->enque(p);
Packet *pp = q_->deque();
drop(pp);
} else {
drop(p);
}

} else {
q_->enque(p);
}
}

//AG if queue size changes, we drop excessive packets...
void myfifo::shrink_queue()
{
int qlimBytes = qlim_ * mean_pktsize_;
if (debug_)
printf("shrink-queue: time %5.2f qlen %d, qlim %d\n",
Scheduler::instance().clock(),
q_->length(), qlim_);
while ((!qib_ && q_->length() > qlim_) ||
(qib_ && q_->byteLength() > qlimBytes)) {
if (drop_front_) { /* remove from head of queue */
Packet *pp = q_->deque();
drop(pp);
} else {
Packet *pp = q_->tail();
q_->remove(pp);
drop(pp);
}
}
}


Packet* myfifo::deque()
{
if (summarystats && &Scheduler::instance() != NULL) {
Queue::updateStats(qib_?q_->byteLength():q_->length());
}
return q_->deque();
}

void myfifo::print_summarystats()
{
//double now = Scheduler::instance().clock();
printf("True average queue: %5.3f", true_ave_);
if (qib_)
printf(" (in bytes)");
printf(" time: %5.3f\n", total_time_);
}

Step 4

Next is to edit ns-default.tcl by performing the followings

a. cd ns-allinone-2.27/ns-2.27/tcl/lib/
b. open ns-default.tcl by editor software
c. look for Queue/DropTail
d. change Queue/DropTail to Queue/myfifo

Queue/DropTail set drop_front_ false
Queue/DropTail set summarystats_ false
Queue/DropTail set queue_in_bytes_ false
Queue/DropTail set mean_pktsize_ 500

Queue/myfifo set drop_front_ false
Queue/myfifo set summarystats_ false
Queue/myfifo set queue_in_bytes_ false
Queue/myfifo set mean_pktsize_ 500

Step 5

Edit makefile by adding myfifo.cc into OBJ_CC and re-make Ns-2

a. use editor software to open makefile in ns-allinone-2.27/ns-2.27
b. look for drop-tail.o
c. at the end of line for droptail.o add queue/myfifo

---------------------------------------------

tools/flowmon.o tools/loss-monitor.o queue/queue.o queue/drop-tail.o queue/myfifo.o adc/simple-intserv-sched.o queue/red.o
---------------------------------------------

d. re-make ns-2 by make command

If there is no errors shown, then the module is successfully added.



Step 6

You may test the new module by using myfifo command instead of DropTail and verify the result of the simulation as the same as DropTail.

Here's the summary of how to add a new module in NS-2

1. Prepare the suitable module files (eg. a.cc and a.h)
2. if necessary, make changes to ns-default.tcl
3. edit makefile by adding the necessary module into OBJ_CC eg a.o into OBJ_CC
4. re-make NS-2
5. test the new module

The author would like advise that users should look for the most similiar module to begin with instead of writing everything from scratch.


1 comment:

Anonymous said...

hi

i doing a research work in ad hoc network.i have installed the ns-2.


can any one tell me that how can i add a clustering algorithm to a routing protocol and simulate it on ns-2.

and also is there any restricton that the module we are adding to ns-2 should be implemented in perticu;lar language.

my mail id is ravi.keshare@gmail.com