Friday, 5 June 2015

Motivational video


more on analysis

grep
 ♥    It is a UNIX command to filter a file.
♥    The name comes from “search globally for lines matching the regular
 expression and print them”
♥    grep takes a regular expression on the command line, reads the
standard input or list of files, and outputs the lines containing matches
for the regular expression

grep “@” file1.txt > file2.txt 
Example 1
In the trace file, if you are intersted only in data concerning tcp packtes that went from node 0 to node 2
grep “0 2 tcp” tr1.tr > tr2.tr 
Example 2

In the trace file, if you are interested only in the received packets

grep “^r” tr1.tr > tr2.tr 
Example 3
In the trace file, if you are intersted only in lines the begin with “s” and have “tcp 1020” later

grep “^s” tr1.tr | grep “tcp 1020” > tr2.tr
AWK 
♥    AWK is a general purpose computer language
♥    AWK is designed for processing text-based data, either in files or data 
streams
♥    The name AWK is derived from the surnames of its authors — Alfred Aho,
Peter Weinberger, and Brian Kernighan;
How to run AWK file?
                                     awk -f file1.awk file2.txt
awk -f file1.awk file2.txt > out.txt
    file1.awk :    is a command file
file2.txt :       is a primary input file
out.txt :        is an output file 

  BEGIN { action }
Executes action commands at the beginning of the script execution,

  END { action }
Executes action commands after the end of input.

  /pattern/
Prints any lines matching pattern.

  { action }
Executes action for each line in the input.
 
Example 4
{ print $1 }
Example 5

                BEGIN { FS = “\t” }
               { nl++ }
               { s=s+$4 }
                END { print “average = ” s/nl }

FS : is the Field Separator.
OFS : is the Output Field Separator 
 
Example 6
               { w += NF; c += length}
END { print NR, w, c }

It prints the number of lines, number of words and number of characters in the file. 
 Example 7

AWK supports associative arrays 
              BEGIN { FS=”[^azAZ]+”}
{     for (i=1; i<=NF; i++)
words[tolower($i)]++
}
END {   for (i in words)
print i, words[i]
}

It gets the frequencies of the words.
Example 8
Functions in AWK

                  function Square (number, temp) {
temp = number * number
return temp
}

                  .
.
.
.

print Square(9)              # Prints 81 


 # This program is used to calculate the packet loss rate between nodes 1,2 for     the application having the flow id = 2
BEGIN {
# Initialization. fsDrops: packets drop. numFs: packets sent
fsDrops = 0;
numFs = 0;
}
{
action = $1; time = $2;
from = $3; to = $4;
type = $5; pktsize = $6;
flow_id = $8; src = $9;
dst = $10; seq_no = $11;
packet_id = $12;
if (from==1 && to==2 && action == “+”)
numFs++;
if (flow_id==2 && action == “d”)
fsDrops++;
}
END {
printf(“number of packets sent:%d lost:%d\n”, numFs, fsDrops);
}
Example 8:
Standard deviation
BEGIN {FS=”\t”} {ln++} {d=$2-t} {s2=s2=d*d} END {print “standev: ” sqrt (s2/ln)}
 /* command to run*/     awk -f  average.awk out.tr

 Example 9:
Array of calculating average and standard deviation
BEGIN { FS = “\t”} {val[n1]=$4} { n1++ } {s=s+$4} END {
av=s/n1
for (i in val) {
d=val[i]-av
s2=s2+d*d
}
print “average: ” av ” standev ” sqrt(s2/n1)}

Example 10
Adding Columns
BEGIN {FS=”\t”}{l1=$2+$3+$4}{l2=$5+$6+$7} \
{print $1″\t” l1″\t” l2″\t”} END {}
  /* command to run*/     awk -f  sumcolumn.awk out.tr > outfile

To use tool (i.e awk) to filter only interesting events
set tr [open "| awk -f filter.awk >out.tr" w]
    $ns trace-all $tr

    .if You are not interested in traces and only results (average, 
variation, distribution, count etc.)

   set tr [open "| awk -f my_measure_tool.awk >my_results.txt" w]
    $ns trace-all $tr

The below is a awk script to analyze several parameters (average e-2-e delay,
pdf, normalised routing load and dropped packets,..) for aodv old trace file
format.

BEGIN {

droppedAODVPackets=0;
sends=0;
recvs=0;

# highest packet id can be checked in the trace file for an approximate value
highest_packet_id =500000;
sum=0;
AODV_Adv=0;
}

{
   action = $1;
   time = $2;
   node_1 = $3;
   node_2 = $4;
   src = $5;

# For stand alone ad hoc trace files:
#   if ( packet_id > highest_packet_id ) highest_packet_id = packet_id;

# For wired- and cireless trace files.

      if ($5 =="cbr") {
      packet_id = $12;
      } else {
      packet_id = $6; 
      }

#============= CALCULATE DELAY   =========================================
   # getting start time is not a problem, provided you're not starting
   # traffic at 0.0.
   # could test for sending node_1_address or flow_id here.

 if ( start_time[packet_id] == 0 )  start_time[packet_id] = time;

   # only useful for small unicast where packet_id doesn't wrap.
   # checking receive means avoiding recording drops
   if ( action != "d" ) {
      if ( action == "r" ) {
       # could test for receiving node_2_address or flow_id here.
         end_time[packet_id] = time;
   }
   } else {
      end_time[packet_id] = -1;
   }
#============= CALCULATE PACKET DELIVERY FRACTION============================
# $3 = source node id , here I have 4 source nodes and start my analysis after
490 seconds of simulation  (when traffic started)
if (( $1 == "s") &&  ( $7 == "cbr" ) && ( $4
=="AGT" ) && ( ( $3== "_5_" )   || ( $3==
"_6_" )   ||  ($3=="_7_")  ||  ($3=="_8_")  
)&& ($2 > 490.00 )    ) {
      sends++;}

# $4 = destination node in wired segment of network. if you simulate ad hoc only
scenario the change $4 to $3 and %5 to $7.
if ( ( $1 == "r") &&  ( $5 == "cbr" ) && (
$4 == "0" ) && ($2 >  490.00 ) ) {
      recvs++;}

pdf = (recvs/sends)*100;

#==================== ADVERTISEMENTS ==================

if ( (($1=="f")  || ($1=="s") ) && ($4 ==
"RTR") && ($7 =="AODV" ) && ($2 > 490.00
) ) { 
AODV_Adv++;
}

#============= DROPPED AODV PACKETS ========================================
if ( ($1 == "D") && ($7=="cbr")  && ($2 >
490.00 ) ){
        droppedAODVBytes=droppedAODVBytes+$8 ;
        droppedAODVPackets=droppedAODVPackets+1;  
    }

}                                           
END {
    for ( packet_id = 0; packet_id <= highest_packet_id; packet_id++ ) {
       start = start_time[packet_id];
       end = end_time[packet_id];
       packet_duration = end - start;
   if ( start < end ) sum= packet_duration+sum;
}
delay=sum/recvs;

printf(" Average e-e delay: \t %f \n", delay);

printf(" normalised routing load \t %f \n ", AODV_Adv/recvs);

printf("No. of packets sent = %d \n", sends);
printf(" No. of packets received = %d \n", recvs);
printf(" Pdf (100%) = %f \n \n", pdf);

printf("No. of dropped data (packets) = %d \n ",droppedAODVPackets);
printf("No. of dropped data (bytes) = %d \n \n ",droppedAODVBytes);
printf("No. of aodv advertisements = %f \n ",AODV_Adv);
}

Thursday, 4 June 2015

GREP FUNCTION: EASY SEARCH COMMAND



Friends,
     Now we are trying to explain a Linux command which helps you a lot in your researches. Its nothing but a simple command called as GREP. It is a powerful command which helps you to search a particular string or words from a file or from a folder and also in some cases it helps during trace file analysis.

SYNTAX

Here the syntax is;
grep <option> <string> <filename>
Here, this command search string within the file named as filename. If it is not given, then the command waits for the input from the keyboard and search for string.  For more about this Click here 
There are two important notes for <string>
  • If it contains a white space,  embrace it with quotation marks ("")
  • If it contains a special character such as “ or &, you can suppress it using backslashes (\” or \&)  to indication that this is a character
For example, If u need to search a word "apple" in a file named as word.txt. Then;
grep apple word.txt
In case of searching words in sub directories, Simply write as; 
                                                                      grep -r apple *

If you want to look a function is available with ns2 folder or not, simply you can search by using this command. For example if you want to find function  className::rt_resolve(ReturnType variableName)
You can find this function using grep:  grep -r ::rt_resolve( *

In case of searching a string with special character "&hdr_aodv", we can search it as;
 grep -r \&hdr_aodv *

if you’re interested only in the ns-2.35/aodv directory. Now ypu can search by using this:
grep rt_resolve aodv/*.*

Now you can filter the search by providing  the files extension along with the search.For example;
grep rt_resolve *.h  searches rt_resolve in .h files only.
While in the case of trace file analysis we can use it as follows;
cat out.tr | grep " 2 3 cbr " | grep ^r | column 1 10 | awk '{dif = $2 - old2; if(dif==0) dif = 1; if(dif > 0) {printf("%d\t%f\n", $2, ($1 - old1) / dif); old1 = $1; old2 = $2}}' > jitter.txt
This means that the "CBR packet receive" event at n3, selects time (column 1) and sequence number (column 10), and calculates the difference from last packet receive time divided by difference in sequence number (for loss packets) for each sequence number. i .e  for selecting particular value we can use this.

Wednesday, 3 June 2015

Protoname in ns2.35




This is an Implementation tutorial of new manet(Mobile Ad-hoc NETworks) unicast protocol name protoname.

The whole credit goes to Francisco J. Ros and Pedro M. Ruiz for their beautiful work and excellent explanation they provide. The link to their work is below. It contains a PDF file also which explains you in detail and I recommend you to go through it once.

List of files to be modified

  • ~/ns-allinone-2.35/ns-2.35/common/packet.h
  • ~/ns-allinone-2.35/ns-2.35/trace/cmu-trace.h
  • ~/ns-allinone-2.35/ns-2.35/trace/cmu-trace.cc
  • ~/ns-allinone-2.35/ns-2.35/tcl/lib/ns-packet.tcl
  • ~/ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl 
  • ~/ns-allinone-2.35/ns-2.35/tcl/lib/ns-lib.tcl
  • ~/ns-allinone-2.35/ns-2.35/queue/priqueue.cc

 
** Note: Text in red is the part that is to be added or modified in given file and location and purple colour denotes the terminal commands.

** Note: mod stands for modification.

** Note: Line number is approx and is provided for your convenience. Please check the methods below and above before inserting.

Step 1:

download protoname.rar

http://www.cs.nccu.edu.tw/~g10031/protoname.rar

Extract the files and place them in ~/ns-allinone-2.35/ns-2.35/protoname directory(create the directory if not present)

Step 2:

gedit ~/ns-allinone-2.35/ns-2.35/common/packet.h (mods at 3 places)

  • a.       its somewhere near line 200

static const packet_t PT_DCCP = 63;
static const packet_t PT_DCCP_REQ = 64;
static const packet_t PT_DCCP_RESP = 65;
static const packet_t PT_DCCP_ACK = 66;
static const packet_t PT_DCCP_DATA = 67;
static const packet_t PT_DCCP_DATAACK = 68;
static const packet_t PT_DCCP_CLOSE  = 69;
static const packet_t PT_DCCP_CLOSEREQ = 70;
static const packet_t PT_DCCP_RESET = 71;

        // M-DART packets
static const packet_t PT_MDART = 72;

        // insert new packet types here

static const packet_t PT_PROTONAME = 73;

static packet_t       PT_NTYPE = 74; // This MUST be the LAST one


  • b. near line 250

static bool data_packet(packet_t type) {
return ( (type) == PT_TCP || \
        (type) == PT_TELNET || \
        (type) == PT_CBR || \
        (type) == PT_AUDIO || \
        (type) == PT_VIDEO || \
        (type) == PT_ACK || \
        (type) == PT_SCTP || \
        (type) == PT_SCTP_APP1 || \
        (type) == PT_HDLC || \  //(remember this mod also)
(type) == PT_PROTONAME \ 
       );

  • c.      near line 422
static void initName()
{
                .....
                name_[PT_DCCP_REQ]="DCCP_Request";
name_[PT_DCCP_RESP]="DCCP_Response";
name_[PT_DCCP_ACK]="DCCP_Ack";
name_[PT_DCCP_DATA]="DCCP_Data";
name_[PT_DCCP_DATAACK]="DCCP_DataAck";
name_[PT_DCCP_CLOSE]="DCCP_Close";
name_[PT_DCCP_CLOSEREQ]="DCCP_CloseReq";
name_[PT_DCCP_RESET]="DCCP_Reset";
name_[PT_PROTONAME]="protoname"; 
name_[PT_NTYPE]= "undefined";
}


save and close.

Step 3:  

gedit ~/ns-allinone-2.35/ns-2.35/trace/cmu-trace.h (mod at 1 place)

  • a. Near line 164.

class CMUTrace: public Trace {
public:
CMUTrace (const char * s, char t);
...
private:
char tracename [MAX_ID_LEN + 1];
int nodeColor [MAX_NODE];
...
void format_tora (Packet * p, int offset);
void format_imep (Packet * p, int offset);
void format_aodv (Packet * p, int offset);
/ / ----------------------------------------------
void format_protoname (Packet *p, int offset);
/ / ----------------------------------------------
void format_aomdv (Packet * p, int offset);
void format_mdart (Packet * p, int offset);

/ / This holds all the tracers added at run-time
static PacketTracer * pktTrc_;

};
# Endif / * __ cmu_trace__ * /

save and close.

Step 4:

gedit ~/ns-allinone-2.35/ns-2.35/trace/cmu-trace.cc (mods at 3 places)

  • a. Add this line at start

#include <protoname/protoname_pkt.h>

  • b. Near line 1168
void
CMUTrace :: format_mdart (Packet * p, int offset)  {

.........
........
........
}

void
CMUTrace::format_protoname(Packet *p, int offset)
{
    struct hdr_protoname_pkt* ph = HDR_PROTONAME_PKT(p);
    if (pt_->tagged())
    {
            sprintf(pt_->buffer() + offset, "-protoname:o %d -protoname:s %d -protoname:l %d ", ph->pkt_src(), ph->pkt_seq_num(), ph->pkt_len());
        }
    else if (newtrace_)
    {
            sprintf(pt_->buffer() + offset, "-P protoname -Po %d -Ps %d -Pl %d ", ph->pkt_src(), ph->pkt_seq_num(), ph->pkt_len());
        }
    else
    {
            sprintf(pt_->buffer() + offset, "[protoname %d %d %d] ", ph->pkt_src(), ph->pkt_seq_num(), ph->pkt_len());
        }
}



  • c. Near line 1477
void CMUTrace :: format (Packet * p, const char * why)
{...
switch (ch-> ptype ()) {
case PT_MAC:
...
case PT_GAF:
case PT_PING:
break;
/ / --------------------------------------------
case PT_PROTONAME:
format_protoname(p, offset);
break;
/ / --------------------------------------------
default:
...
}

save and close.

Step 5:

gedit ~/ns-allinone-2.35/ns-2.35/tcl/lib/ns-packet.tcl  (mod at 1 place)

  • a. Near line 172

# Mobility, Ad-Hoc Networks, Sensor Nets:
    AODV     # routing protocol for ad-hoc networks
    Protoname # new routing protocol for ad-hoc networks
    Diffusion     # diffusion/diffusion.cc
    IMEP     # Internet MANET Encapsulation Protocol, for ad-hoc

Save and close.

Step 6:

gedit ~/ns-allinone-2.35/ns-2.35/tcl/lib/ns-default.tcl  (mod at 1 place)

  • a. Add at the last.

# Defaults defined for Protoname
Agent/Protoname set accessible_var_ true


save and close.

step 7:

gedit ~/ns-allinone-2.35/ns-2.35/tcl/lib/ns-lib.tcl  (mod at 2 places)

  • a. Near line 671

switch-exact $ routingAgent_ {
...
ManualRtg {
set ragent [$ self create-manual-rtg-agent $
}
# / ------------------------------------------------ -
Protoname 
{
         set ragent [$self create-protoname-agent $node]

}
# / ------------------------------------------------ -
default {
...
}


  • b. Near line 2278

Simulator instproc create-omnimcast-agent {node} {
...
}
# / ------------------------------------------------ -----
Simulator instproc create-protoname-agent {node} {
    # Create Protoname routing agent
    set ragent [new Agent/Protoname [$node node-addr]]
    $self at 0.0 "$ragent start"
    $node set ragent_ $ragent
    return $ragent
}

# / ------------------------------------------------ -----
# XXX These are very simulation-specific methods, why should they belon
Simulator instproc put-in-list {agent} {
...
}


Step 8:

gedit ~/ns-allinone-2.35/ns-2.35/queue/priqueue.cc (mod at 1 place)

  • a. Near line 95.
void
PriQueue :: recv (Packet * p, Handler * h)
{
struct hdr_cmn * ch = HDR_CMN (p);

if (Prefer_Routing_Protocols) {
switch (ch-> ptype ()) {
...
case PT_MDART:
/ / --------------------------------------------
case PT_PROTONAME:
/ / --------------------------------------------
recvHighPriority (p, h);
break;
default:
Queue :: recv (p, h);
}
}
else {
Queue :: recv (p, h);
}
}

save and close.

Step 9:

gedit ~/ns-allinone-2.35/ns-2.35/Makefile (mod at 1 place)

  • a. Near line 336

OBJ_CC = \
tools / random.o tools / rng.o tools / ranvar.o common / misc.o common /
...
wpan/p802_15_4trace.o wpan/p802_15_4transac.o \
apps / pbc.o \
# / / ----------------------------------------------- -
protoname/protoname.o protoname/protoname_rtable.o \
# / / ----------------------------------------------- -
$ (OBJ_STL)

save and close.

Step 10:

build it now, changes done ( run these in terminal in ~/ns-allinone-2.35/ns-2.35 directory )

  • a. make clean
  • b. touch common/packet.cc
  • c. make

(if you are getting some errors check the spaces in the editing you did above)


Step 11:

gedit ~/ns-allinone-2.35/ns-2.35/test.tcl

copy and paste

set ns [new Simulator]
$ns node-config -Routing protoname   
set nf [open out.nam w]     
$ns namtrace-all $nf       
set nd [open out.tr w]       
$ns trace-all $nd             
  proc finish {} {
          global ns nf  nd
          $ns flush-trace 
          close $nf       
          close $nd       
          exec nam out.nam &
          exit 0
   }

for {set i 0} {$i < 7} {incr i} {set n($i) [$ns node] }
for {set i 0} {$i < 7} {incr i} {
$ns duplex-link $n($i) $n([expr ($i+1)%7]) 1Mb 10ms DropTail
}
set udp0 [new Agent/UDP]   
$ns attach-agent $n(0) $udp0
set cbr0 [new Application/Traffic/CBR] 
$cbr0 set packetSize_ 500     
$cbr0 set interval_ 0.005      
$cbr0 attach-agent $udp0
set null0 [new Agent/Null]
$ns attach-agent $n(3) $null0
$ns connect $udp0 $null0 
$ns at 0.5 "$cbr0 start"
$ns rtmodel-at 1.0 down $n(1) $n(2) 
$ns rtmodel-at 2.0 up $n(1) $n(2)   
$ns at 4.5 "$cbr0 stop"
$ns at 5.0 "finish"
$ns run


save and close

ns ~/ns-allinone-2.35/ns-2.35/test.tcl

and boom you are getting the nam (if not sorry troubleshoot once by going through the tutorial again as I am getting the outputs completely and so should you) 

Friday, 22 May 2015

Packet delivery ratio, Packet Lost, End to end delay

Packet delivery ratio, Packet Lost, End to end delay

If you want to evaluate the performance of protocol using NS-2, first you have to define the evaluation criteria. This time I want to explore about Packet delivery ratio, packet lost and end to end delay.
What are they??
Packet delivery ratio : the ratio of the number of delivered data packet to the destination. This illustrates the level of delivered data to the destination.
∑ Number of packet receive / ∑ Number of packet send
The greater value of packet delivery ratio means the better performance of the protocol.
End-to-end Delay : the average time taken by a data packet to arrive in the destination. It also includes the delay caused by route discovery process and the queue in data packet transmission. Only the data packets that successfully delivered to destinations that counted.
∑ ( arrive time – send time ) / ∑ Number of connections
The lower value of end to end delay means the better performance of the protocol.
Packet Lost : the total number of packets dropped during the simulation.
Packet lost = Number of packet send – Number of packet received .
The lower value of the packet lost means the better performance of the protocol.
How to analyze trace file to find the result?
First : you must analyze the trace file with this Script PDR and E2ED
run this script with command :
awk -f PacketDeliveryRatio.awk (name trace file.tr)
awk -f Endtoenddelay.awk (name trace file.tr)

Monday, 4 May 2015

Modification of RED AQM in NS2

Please read the previous post here first to get some background information about RED.
0. Download ns2, Compile it and Install it.
This is a preparation step. It’s not the focus of this post, please refer to reference 1 for details. Note that since we’re going to modify NS2, we’ll need to download and source code and build it ourselves.  
1. Change red.cc and red.h
RED calculates the probability of dropping a packet by 2 steps when average queue size falls in between th_min and th_max. The first step is to calculate a probability called Pb, which is based on the formula below,

Pb = Pmax*(avg – th_min)/(th_max-th_min)                                        (1)
It can be seen that the probability Pb is calculated based on a linear function.
In the second step, RED counts the number of packets have gone through the gateway (count) since last packet is dropped from the flow and apply the following formula,

Pa = Pb / (1 – count*Pb)                                                                             (2)
In this part, we modified the first step by applying 4 different functions to calculate Pb and compare the results. The curves for the 4 functions are roughly as below,
image
Figure 1. Five Different Functions to Evaluate Pb
1.1 Analysis
You can ignore this part and jump to 1.2 if you only want to know how to change a protocol in NS2.
NS2 RED queue implementation doesn’t use the formula (1) above directly, instead it uses the formula below,

Pb = Pmax*(v_a * v_ave + v_b)                                                       (3)
where v_a = 1.0 / (th_max – th_min), v_ave is the average queue size, and v_b = -th_min / (th_max – th_min). This forumla is equivalent to formula (1).
For concave function v1, we use log function,

Pb = Pmax*(m*log(v_ave) + n)                                                        (4)
As the curve intersects with original linear function at th_min and th_max, we have the following,

0 = Pmax*(m*log(th_min) + n)                                                         (5)
Pmax = Pmax*(m*log(th_max + n))                                                 (6)
Also the original linear function gives us the function,

0 = Pmax*(v_a*th_min + v_b)                                                          (7)
with (5) (6) and (7), we can get values for m and n in formula (4),

m = 1/(log(th_max) – log(-v_b/v_a))                                                (8)
n = -m*log(-v_b/v_a)                                                                          (9)
Similarly, we can express the formula for function v4 the convex function (we chose exponential function) using th_max, v_b and v_a as below,

Pb = Pmax*(m*exp(v_ave)+n)                                                          (10)
where,

m = 1/(exp(th_max) – exp(-v_b/v_a))                                             (11)
n = -m*exp(-v_b/v_a)                                                                       (12)
As for function v2 and v3, which are piecewise linear functions, we express the functions as below,

Pb = Pmax*(m*v_ave + p) when v_ave in [th_min, (th_min+th_max)/2] (13)
Pb = Pmax*(n*ave + q) when v_ave in [(th_min+th_max)/2, th_max]
We can get the following equations,

m*th_min + p = 0                                                                                  (14)
m*[(th_min+th_max)/2] + p = n*[(th_min+th_max)/2] + q         (15)
n*th_max + q = 1                                                                                  (16)
With (14), (15) and (16), we can derive the relationship between m and n,

n = [m*(th_max+th_min)/2 – m*th_min] / [(th_max+th_min)/2 – th_max]                                                                                                 (17)
For function v2, we set m = 1.2*v_a, so we have,

p = -1.2*v_a*th_min                                                                            (18)
n = [1.2*v_a*(th_max+th_min)/2 – 1.2*v_a*th_min] / [(th_max+th_min)/2-th_max]                                                                                                 (19)
q = 1 – n*th_max                                                                                   (20)
For function v3, we set m = 0.8*v_a, so we have,

p = -0.8*v_a*th_min                                                                             (21)
n = [0.8*v_a*(th_max+th_min)/2 – 0.8*v_a*th_min] / [(th_max+th_min)/2-th_max]                                                                                                  (22)
q = 1 – n*th_max                                                                                    (23)
1.2 Changes the Source Code
In order to add the four different evaluation functions for Pb and make it configurable, we’ll need to add a new input parameter in red.h. We add a variable func to the data structure edp.
struct edp {
    /*
     * User supplied.
     */
    int mean_pktsize;    /* avg pkt size, linked into Tcl */
    int idle_pktsize;    /* avg pkt size used during idle times */
    int bytes;        /* true if queue in bytes, false if packets */
    int wait;        /* true for waiting between dropped packets */
    int setbit;        /* true to set congestion indication bit */
    int gentle;        /* true to increases dropping prob. slowly *
                 * when ave queue exceeds maxthresh. */
    double th_min;        /* minimum threshold of average queue size */
    double th_min_pkts;    /* always maintained in packets */
    double th_max;        /* maximum threshold of average queue size */
    double th_max_pkts;     /* always maintained in packets */
    double max_p_inv;       /* 1/max_p, for max_p = maximum prob.  */
                            /* adaptive RED: the initial max_p_inv     */    
    double mark_p;        /* when p < mark_p, mark chosen packets */
                /* when p > mark_p, drop chosen packets */
        int use_mark_p;        /* use mark_p only for deciding when to drop, */
                /*   if queue is not full */
                /* Set use_mark_p true and set mark_p to 2.0 */
                /*   to always mark instead of drop */
                /*   when queue is not full */
    double q_w;        /* queue weight given to cur q size sample */
    int adaptive;        /* 0 for default RED */
                /* 1 for adaptive RED, adapting max_p */
    int cautious;           /* 0 for default RED */
                                /* 1 for not dropping/marking when the */
                                /*  instantaneous queue is much below the */
                                /*  average */
    double alpha;           /* adaptive RED: additive param for max_p */
    double beta;            /* adaptive RED: multip param for max_p */
    double interval;    /* adaptive RED: interval for adaptations */
    double targetdelay;     /* adaptive RED: target queue size */
    double top;        /* adaptive RED: upper bound for max_p */
    double bottom;        /* adaptive RED: lower bound for max_p */
                /* 0 for automatic setting */
    int feng_adaptive;    /* adaptive RED: Use the Feng et al. version */
            
    /*
     * Computed as a function of user supplied paramters.
     */
    double ptc;        /* packet time constant in packets/second */
    double delay;        /* link delay */
    int func;        /* function used to calculate Pb*/
};
In red.cc, we first bind the variable in the REDQueue constructor REDQueue::REDQueue,
bind(“function_”, &edp_.func);            //roman10: function number: 0~4
Then we change the calculate_p_new function as below,
/*
 * Calculate the drop probability.
 */
double
REDQueue::calculate_p_new(double v_ave, double th_max, int gentle, double v_a, 
    double v_b, double v_c, double v_d, double max_p)
{
    double p;
    double lm, ln, lp, lq, Xmin;
    if (gentle && v_ave >= th_max) {
        // p ranges from max_p to 1 as the average queue
        // size ranges from th_max to twice th_max 
        p = v_c * v_ave + v_d;
        } else if (!gentle && v_ave >= th_max) { 
                // OLD: p continues to range linearly above max_p as
                // the average queue size ranges above th_max.
                // NEW: p is set to 1.0 
                p = 1.0;
        } else {
                // p ranges from 0 to max_p as the average queue
                // size ranges from th_min to th_max 
        if (edp_.func == 1) {
            lm = 1.0/(log(th_max) - log(-v_b/v_a));
            ln = -lm*log(-v_b/v_a);
            p = lm*log(v_ave) + ln;
        } else if (edp_.func == 2) {
            Xmin = -v_b/v_a;
            if (v_ave < (th_max + Xmin)/2) {
                lm = 1.2*v_a;
                lp = -lm*Xmin;
                p = lm * v_ave + lp;
            } else {
            ln = (1.2*v_a*(th_max+Xmin)/2-1.2*v_a*Xmin)/((th_max+Xmin)/2-th_max);
                lq = 1.0 - ln*th_max;
                p = ln * v_ave + lq;
            }
        } else if (edp_.func == 3) {
            if (v_ave < (th_max - v_b/v_a)/2) {
            lm = 0.8*v_a;
            lp = v_b*lm/v_a;
            p = lm*v_ave + lp;            
            } else {
            ln = (0.8*v_a*(th_max+Xmin)/2-0.8*v_a*Xmin)/((th_max+Xmin)/2-th_max);
            lq = 1.0 - ln*th_max;
                p = ln * v_ave + lq;
            }
        } else if (edp_.func == 4) {
            lm = 1.0/(exp(th_max) - exp(-v_b/v_a));
            ln = -lm*exp(-v_b/v_a);
            p = lm*exp(v_ave) + ln;
            //printf("%f, %f, %f, %f\n", exp(th_max), exp(-v_b/v_a), lm, v_ave);
        } else {
                p = v_a * v_ave + v_b;
        }
                // p = (v_ave - th_min) / (th_max - th_min)
                p *= max_p; 
        }
    if (p > 1.0)
        p = 1.0;
    return p;
}
2. Change ns-default.tcl
We update ns-2.35/tcl/lib/ns-default.tcl file by adding the following to red queue configuration section (search for Qeueu/RED, and add it at some lines nearby),
Queue/RED set function_ 0
This line sets the function_ to be 0 if user doesn’t supply the function_ value.
3. Test the Changes
One can run the simulation configured below to see if our changes work or not.
set ns [new Simulator]
 
#    s1                             
#       -                       
#          -                   
#    s2 ----- r1            
#                 -       
#    -                r3  - - - - - D1    
#    -            -
#             -
#    S50   -
 
set NumSenders 50
set NumReceivers 1
#read scenario, seed and bottleneck bandwidth from the command line input arguments
set Scenario [lindex $argv 0]
set function [lindex $argv 1]
set seed [lindex $argv 2]
 
puts "scenario: $Scenario; function: $function; seed: $seed"
ns-random $seed
set BufSize 100
set PktSize 1024 
#set winSize 200
#in seconds
set Duration 50 
#create all nodes: note that the order of creating the nodes matter
for {set i 1} {$i <= $NumSenders} {incr i} {
    set s($i) [$ns node]
}
set r1 [$ns node]
set d1 [$ns node]
 
 
#open the nam trace file
set nf [open out.nam w]
$ns namtrace-all $nf
 
#open the traffic trace file to record all events
set nd [open out.tr w]
$ns trace-all $nd
 
#define a finish procedure
proc finish {} {
    global ns nf nd qtf
    $ns flush-trace
    close $nf
    close $nd
    close $qtf
    #start nam
    #exec nam out.nam &
    exit 0
}
 
#link the nodes
if { $Scenario == 1 } {
    Queue/RED set thresh_ 15
    Queue/RED set maxthresh_ 45
} elseif { $Scenario == 2 } {
    Queue/RED set thresh_ 20
    Queue/RED set maxthresh_ 60
} elseif { $Scenario == 3 } {
    Queue/RED set thresh_ 25
    Queue/RED set maxthresh_ 75
} elseif { $Scenario == 4 } {
    Queue/RED set thresh_ 30
    Queue/RED set maxthresh_ 90
}
Queue/RED set queue_in_bytes_ false
Queue/RED set gentle_ false
Queue/RED set function_ $function
 
for {set i 1} {$i <= $NumSenders} {incr i} {
    $ns duplex-link $s($i) $r1 10Mb 100ms DropTail
    $ns queue-limit $s($i) $r1 $BufSize
}
#r1 d1 and d1 r1 are different
$ns duplex-link $r1 $d1 3Mb 100ms RED
$ns queue-limit $r1 $d1 $BufSize
 
#trace the queue: note that link r1 d1 is different from d1 r1
set redq [[$ns link $r1 $d1] queue]
set qtf [open queue.txt w]
$redq trace curq_
$redq trace ave_
$redq attach $qtf
 
#set up TCP connections
for {set i 1} {$i <= $NumSenders} {incr i} {
    set tcp($i) [new Agent/TCP]
    $ns attach-agent $s($i) $tcp($i)
    set sink($i) [new Agent/TCPSink]
    $ns attach-agent $d1 $sink($i)
    $ns connect $tcp($i) $sink($i)
    $tcp($i) set fid_ $i
    $tcp($i) set packetSize_ $PktSize
    #$tcp($i) set window_ $winSize
    #set up FTP over TCP connection as traffic source
    set ftp($i) [new Application/FTP]
    $ftp($i) attach-agent $tcp($i)
    $ftp($i) set type_ FTP
}
 
#schedule events for the FTP agents
set StartTime [expr [ns-random]  / 2147483647.0 / 100]
puts "starttime $StartTime"
#temporarily set to 2
for {set i 1} {$i <= $NumSenders} {incr i}  {
    $ns at $StartTime "$ftp($i) start"
    $ns at $Duration+$StartTime "$ftp($i) stop"
}
#ensure the ftp application have enough time to finish, so we +1
$ns at $Duration+$StartTime+1 "finish"
 
#run the simulation
$ns run
 
Supposed we save the file as b.tcl, a sample command to run it,
ns b.tcl 4 1 100
4. Results
I run a simulation using the 5 different evaluation functions, below are the plots of average queue size and instance queue versus time. The red lines are the average queue size and green lines are instance queue size.
imageimage
imageimage
image
Figure 2. Average Queue Size and Instance Queue Size versus Time
From the plot, we can see that v1 and v2 keeps the average queue size at a lower level than regular RED, while v3 and v4 keeps the average queue size at a higher level than regular RED. This is expected as v1 and v2 are always above the original linear function given the same average queue size value in the range of [th_min, th_max], in other words, v1 and v2 are more aggressive in terms of dropping packets when the average queue size is between th_min and th_max. On the contrast, v3 and v4 are less aggressive than regular RED.
5. Download
You can download the files mentioned in this post here.
Follow the instructions below to apply the changes (you’ll need gnuplot to plot the figures),
1. Apply the changes
1.1 copy red.cc and red.h to ns-allinone-2.34/ns-2.34/queue/
1.2 copy ns-default.tcl to ns-allinone-2.34/ns-2.34/tcl/lib/
1.3 at command line, go to ns-allinone-2.34/ns-2.34/, “sudo make”
2. Run the simulation and plot figures: ./b.py
References:
1. How to Install NS2.34 in Ubuntu: http://www.scribd.com/doc/46784839/Install-NS2-34-in-Ubuntu10-10
2. Problem description in detail http://www.comp.nus.edu.sg/~tbma/teaching/cs5229/NS2_Assignment.pdf