To run NS-2, we need two executables, usually called ns and nam. ns is the ``executable'' (some people say ``binary'') that does the actual ``network simulation'' work. nam is the executable that sets up a ``network animation'', i.e. it shows a diagram of the network you are simulating, with nodes (hosts, routers), links, etc, and it shows the packets moving along the links, or falling on the floor when packet drop occurs. I have obtained both executables and put them together in a directory called ``exec'': maan-107 exec>: ls -l total 14212 -rwxr-xr-x 1 ott 30 2546856 Aug 30 14:25 nam -rwxr-xr-x 1 ott 30 4728572 Aug 30 14:19 ns Please note both files are executable. We still need to tell ns what network we want simulated, what kinds of hosts, routers, we want, what kinds of links we want (linkspeed, propagation delays), how large buffers must be, what kind of queueing discipline we want, what kinds of flows we want (UDP, TCP, ...), what kind of TCP we want (Tahoe, Reno, NewReno, Vegas, ...), etc. All this information we collect in a so-called .tcl file. Mr Raizada made a nice .tcl file for me, called 2tcp_1node.tcl . I am copying that file into the directory exec. The result is: maan-112 exec>: ls -l total 14220 -rw-r--r-- 1 ott 30 3445 Sep 1 16:07 2tcp_1node.tcl -rwxr-xr-x 1 ott 30 2546856 Aug 30 14:25 nam -rwxr-xr-x 1 ott 30 4728572 Aug 30 14:19 ns (Here follows a copy of 2tcp_1node.tcl:) # the experimentation with NS continues set ns [new Simulator] set nf [open out.nam w] $ns namtrace-all $nf set f [open out.tr w] $ns trace-all $f $ns color 1 blue $ns color 2 red $ns color 3 green proc finish {} { global ns f nf $ns flush-trace close $nf close $f exec nam out.nam & exit 0 } #creating NODES set n0 [$ns node] set n1 [$ns node] set n2 [$ns node] set n3 [$ns node] set n4 [$ns node] #Creating links #link between n0 and n1 $ns simplex-link $n0 $n1 1.5Mb 5.0ms DropTail #link between n1 and n0 $ns simplex-link $n1 $n0 1.5Mb 5.0ms DropTail #link between n1 and n2 $ns simplex-link $n1 $n2 1.5Mb 2.0ms DropTail #link between n2 and n1 $ns simplex-link $n2 $n1 1.5Mb 2.0ms DropTail #link between n2 and n3 $ns simplex-link $n2 $n3 1.5Mb 2.0ms DropTail #link between n3 and n2 $ns simplex-link $n3 $n2 1.5Mb 2.0ms DropTail #link between n2 and n4 $ns simplex-link $n2 $n4 1.5Mb 2.0ms DropTail #link between n3 and n2 $ns simplex-link $n4 $n2 1.5Mb 2.0ms DropTail #creating the buffers in the nodes #sets the position of the queue to view in NAM $ns simplex-link-op $n0 $n1 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n0 $n1 4 #sets the position of the queue to view in NAM $ns simplex-link-op $n1 $n0 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n1 $n0 4 #sets the position of the queue to view in NAM $ns simplex-link-op $n1 $n2 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n1 $n2 4 #sets the position of the queue to view in NAM $ns simplex-link-op $n2 $n1 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n2 $n1 4 #sets the position of the queue to view in NAM $ns simplex-link-op $n2 $n3 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n2 $n3 4 #sets the position of the queue to view in NAM $ns simplex-link-op $n3 $n2 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n3 $n2 4 #sets the position of the queue to view in NAM $ns simplex-link-op $n2 $n4 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n2 $n4 4 #sets the position of the queue to view in NAM $ns simplex-link-op $n4 $n2 queuePos 0.5 #sets the size of the buffer $ns queue-limit $n4 $n2 4 #Creating Traffic # Creating the first TCP traffic. # Node 0 will send TCP traffic generated by FTP application # Node 3 will receive this #creating tcp agent at node 0 set tcp0 [new Agent/TCP] $ns attach-agent $n0 $tcp0 #creating sink at node 3 set sink0 [new Agent/TCPSink] $ns attach-agent $n3 $sink0 #setting TCP parameters $tcp0 set packetSize_ 160 $tcp0 set window_ 25 $tcp0 set windowInit_ 1 $tcp0 set class_ 2 #setting the FTP application set ftp [new Application/FTP] $ftp attach-agent $tcp0 #Creating the second TCP Traffic. #Node 0 will send TCP traffic generated by FTP application #Node 4 will receive this. #creating tcp agent at node 0 set tcp1 [new Agent/TCP] $ns attach-agent $n0 $tcp1 #creating sink at node 4 set sink1 [new Agent/TCPSink] $ns attach-agent $n4 $sink1 #setting TCP parameters $tcp1 set packetSize_ 160 $tcp1 set window_ 25 $tcp1 set windowInit_ 1 $tcp1 set class_ 3 #setting the FTP application set ftp0 [new Application/FTP] $ftp0 attach-agent $tcp1 #making the connections $ns connect $tcp0 $sink0 $ns connect $tcp1 $sink1 # creating the run time sequence $ns at 0.05 "$ftp start" $ns at 0.1 "$ftp0 start" $ns at 0.2 "$ftp stop" $ns at 0.25 "$ftp0 stop" $ns at 3.0 "finish" $ns run (end of copy of 2tcp_1node.tcl) Now we execute ns with as input 2tcp_1node.tcl : maan-116 exec>: ns 2tcp_1node.tcl maan-117 exec>: ls -l total 14484 -rw-r--r-- 1 ott 30 3445 Sep 1 16:07 2tcp_1node.tcl -rwxr-xr-x 1 ott 30 2546856 Aug 30 14:25 nam -rwxr-xr-x 1 ott 30 4728572 Aug 30 14:19 ns -rw-r--r-- 1 ott 30 96661 Sep 1 16:13 out.nam -rw-r--r-- 1 ott 30 37469 Sep 1 16:13 out.tr You see that during the execution two more files were created: out.nam and out.tr. What you did not see is that I got two more windows on my screen. One is an animation of the simulation (drawing of 5 nodes, numbered 0 , 1 , 2 , 3, 4 ). By clicking on the right places I can see packets moving through this diagram, and occasionally dropping on the floor. out.nam is the file containing the data for the animation, and nam is the program that gives the animation. The files out.nam and out.tr are available on this website. Part of out.tr is also given below. The executables ns and nam are available in /usr/local/bin/ (actually: as links in /usr/local/bin/). Since /usr/local/bin/ is in your path, you can call ns and nam from anywhere in afs. For the time being, the file out.tr is of greater interest. This is the so-called ``trace file''. It describes in detail what happens in the simulation. Before discussing the trace file further, I have to tell you what system is being simulated: ____ | | | 3 | |____| / ____ ____ ____/ | | | | | | | 0 |---| 1 |---| 2 | |____| |____| |____| \ \____ | | | 4 | |____| Host 0 is connected with router 1, which is connected with router 2, which is connected with hosts 3 and 4. There are two TCP connections (I think Mr Raizada said these are Tahoe, but the output seems to indicate they are Reno or newReno. Mr Raizada: please check). The first (tcp0) is from host 0 to host 3, the second (tcp1) from host 0 to host 4. Mr Raizada's .tcl file has some ``inelegancies'': tcp0 has source model ftp, while tcp1 has source model ftp0. When you make your own .tcl files, make sure they are easy to read! (For yourself, three weeks later!). tcp0 is the tcp flow from host 0 to host 3. tcp1 is the tcp flow from host 0 to host 4. Excercise: Copy the file out.nam from this website to your directory. Call it (for example) first.nam , then execute prompt>: nam first.nam If all is well, you will see the animation of the simulation run. Play with it! Adjust the speed until you can see individual packets moving and dropping. Note: While the representation of the network ``topologically'' is the same as the picture above, it is likely to look very different. Before worrying about exact syntax of .tcl files, let's look at the output out.tr: We give the first 51 lines of the file out.tr : + 0.05 0 1 tcp 40 ------- 2 0.0 3.0 0 0 - 0.05 0 1 tcp 40 ------- 2 0.0 3.0 0 0 r 0.055213 0 1 tcp 40 ------- 2 0.0 3.0 0 0 + 0.055213 1 2 tcp 40 ------- 2 0.0 3.0 0 0 - 0.055213 1 2 tcp 40 ------- 2 0.0 3.0 0 0 r 0.057427 1 2 tcp 40 ------- 2 0.0 3.0 0 0 + 0.057427 2 3 tcp 40 ------- 2 0.0 3.0 0 0 - 0.057427 2 3 tcp 40 ------- 2 0.0 3.0 0 0 r 0.05964 2 3 tcp 40 ------- 2 0.0 3.0 0 0 + 0.05964 3 2 ack 40 ------- 2 3.0 0.0 0 1 - 0.05964 3 2 ack 40 ------- 2 3.0 0.0 0 1 r 0.061853 3 2 ack 40 ------- 2 3.0 0.0 0 1 + 0.061853 2 1 ack 40 ------- 2 3.0 0.0 0 1 - 0.061853 2 1 ack 40 ------- 2 3.0 0.0 0 1 r 0.064067 2 1 ack 40 ------- 2 3.0 0.0 0 1 + 0.064067 1 0 ack 40 ------- 2 3.0 0.0 0 1 - 0.064067 1 0 ack 40 ------- 2 3.0 0.0 0 1 r 0.06928 1 0 ack 40 ------- 2 3.0 0.0 0 1 + 0.06928 0 1 tcp 200 ------- 2 0.0 3.0 1 2 - 0.06928 0 1 tcp 200 ------- 2 0.0 3.0 1 2 r 0.075347 0 1 tcp 200 ------- 2 0.0 3.0 1 2 + 0.075347 1 2 tcp 200 ------- 2 0.0 3.0 1 2 - 0.075347 1 2 tcp 200 ------- 2 0.0 3.0 1 2 r 0.078413 1 2 tcp 200 ------- 2 0.0 3.0 1 2 + 0.078413 2 3 tcp 200 ------- 2 0.0 3.0 1 2 - 0.078413 2 3 tcp 200 ------- 2 0.0 3.0 1 2 r 0.08148 2 3 tcp 200 ------- 2 0.0 3.0 1 2 + 0.08148 3 2 ack 40 ------- 2 3.0 0.0 1 3 - 0.08148 3 2 ack 40 ------- 2 3.0 0.0 1 3 r 0.083693 3 2 ack 40 ------- 2 3.0 0.0 1 3 + 0.083693 2 1 ack 40 ------- 2 3.0 0.0 1 3 - 0.083693 2 1 ack 40 ------- 2 3.0 0.0 1 3 r 0.085907 2 1 ack 40 ------- 2 3.0 0.0 1 3 + 0.085907 1 0 ack 40 ------- 2 3.0 0.0 1 3 - 0.085907 1 0 ack 40 ------- 2 3.0 0.0 1 3 r 0.09112 1 0 ack 40 ------- 2 3.0 0.0 1 3 + 0.09112 0 1 tcp 200 ------- 2 0.0 3.0 2 4 - 0.09112 0 1 tcp 200 ------- 2 0.0 3.0 2 4 + 0.09112 0 1 tcp 200 ------- 2 0.0 3.0 3 5 - 0.092187 0 1 tcp 200 ------- 2 0.0 3.0 3 5 r 0.097187 0 1 tcp 200 ------- 2 0.0 3.0 2 4 + 0.097187 1 2 tcp 200 ------- 2 0.0 3.0 2 4 - 0.097187 1 2 tcp 200 ------- 2 0.0 3.0 2 4 r 0.098253 0 1 tcp 200 ------- 2 0.0 3.0 3 5 + 0.098253 1 2 tcp 200 ------- 2 0.0 3.0 3 5 - 0.098253 1 2 tcp 200 ------- 2 0.0 3.0 3 5 + 0.1 0 1 tcp 40 ------- 3 0.1 4.0 0 6 - 0.1 0 1 tcp 40 ------- 3 0.1 4.0 0 6 r 0.100253 1 2 tcp 200 ------- 2 0.0 3.0 2 4 + 0.100253 2 3 tcp 200 ------- 2 0.0 3.0 2 4 - 0.100253 2 3 tcp 200 ------- 2 0.0 3.0 2 4 (end of first 51 lines). Explanation: + 0.05 0 1 tcp 40 ------- 2 0.0 3.0 0 0 At time .05 sec, a tcp packet of 40 bytes (i.e., a syn or so) becomes available to the output port in node 0 toward node 1. This is packet 0 (zero) ``globally'' and also packet 0 in its flow. - 0.05 0 1 tcp 40 ------- 2 0.0 3.0 0 0 At time .05 this packet starts leaving node 0 toward node 1. r 0.055213 0 1 tcp 40 ------- 2 0.0 3.0 0 0 At time .055213 this packet arrives at node 1. + 0.055213 1 2 tcp 40 ------- 2 0.0 3.0 0 0 At time .055213 this papcket becomes available to the output port in node 1 toward node 2. - 0.055213 1 2 tcp 40 ------- 2 0.0 3.0 0 0 At time 0.055213 this packet starts leaving node 1 toward node 2. r 0.057427 1 2 tcp 40 ------- 2 0.0 3.0 0 0 At time 0.057427 this packet arrives at node 2. Etc. Jumping a few lines: r 0.05964 2 3 tcp 40 ------- 2 0.0 3.0 0 0 At time 0.05964 the packet arrives at node 3 So this was a packet from host 0 to host 3: A packet of flow tcp0. + 0.05964 3 2 ack 40 ------- 2 3.0 0.0 0 1 Node 3 makes an acknowledgement and makes it available to its output buffer toward node 2. This is packet 1 globally, and it ``acknowledges'' packet 0. (a flow and its opposite direction counterpart are considered different flows). In this simulation, the ``opposite direction'' flow carries no data. It only carries acknowledgements. The architects of NS decided not to give this flow its own name. Aside: a flow and its opposite direction counterpart are often called ``mates''. In ATM this seems to be standard. We infer: The very last number of a line is the ``global'' sequence number of a packet. The next-to-last number either is the sequence number of the packet in its flow (if it is a data packet), or the number of the packet it acknowledges (if it is an acknowledgement packet). (A ``syn'' is considered a datapacket. However, the three-way handshake of TCP is very incompletely modeled.) In THIS simulation run, all tcp connections are ``one way''. One direction has only data packets, the other has only acknowledgements. When we have bidirectional traffic, packets must have a sequence number as well as an ack number. Real TCP ALWAYS has both. Next from the end come the ``IP-addresses and port numbers'' of the packet. The packet that is globally number zero has origination IP address 0 and origination port number 0. It has destination IP address 3 and destination port number 0. The packet that is globally number 1 has origination IP address 3 and origination port number 0. It has destination IP address 0 and destination portnumber 0. A while later: - 0.064067 1 0 ack 40 ------- 2 3.0 0.0 0 1 r 0.06928 1 0 ack 40 ------- 2 3.0 0.0 0 1 + 0.06928 0 1 tcp 200 ------- 2 0.0 3.0 1 2 - 0.06928 0 1 tcp 200 ------- 2 0.0 3.0 1 2 r 0.075347 0 1 tcp 200 ------- 2 0.0 3.0 1 2 At time 0.06928 packet 1 (global), i.e. the acknowledgement, arrives at host zero. This gives tcp0 permission to send a data packet. At time 0.06928 it makes this data packet (200 Bytes large) available to the output port in host 0 toward router 1. This is packet 2 globally and has sequence number 1 in its flow. If you look in the .tcl file, you see that tcp0 has ``packetSize_'' equal to 160 Bytes. So the MSS is 160 Bytes, the total packetsize in transport (as it would appear in the IP header) is 200 Bytes. Again a while later: + 0.1 0 1 tcp 40 ------- 3 0.1 4.0 0 6 At time .1 (sec) a packet (syn) is made available to the output port of node 0, toward node 1. It is globally packet number 6, but has sequence number 0 in its flow. It has source IP address 0 and source port number 1. It has destination IP address 4 and destination port number 0. This must be a packet of tcp1. Question: why does this packet have source port number 1, not 0? I infer that packets of flow tcp0 and its mate have a 2 in the column just before the IP addresses and portnumbers, while packets of flow tcp1 and its mate have a 3 in that column. I assume this is the ``class'' of the TCP connection as given in the .tcl file. Again a while later (not in the first 51 lines, see the file out.tr on this website) we get: - 0.135907 1 0 ack 40 ------- 3 4.0 0.1 1 19 r 0.136933 1 0 ack 40 ------- 2 3.0 0.0 6 17 + 0.136933 0 1 tcp 200 ------- 2 0.0 3.0 12 24 + 0.136933 0 1 tcp 200 ------- 2 0.0 3.0 13 25 d 0.136933 0 1 tcp 200 ------- 2 0.0 3.0 13 25 - 0.136933 0 1 tcp 200 ------- 2 0.0 3.0 10 22 r 0.138 1 0 ack 40 ------- 2 3.0 0.0 7 18 + 0.138 0 1 tcp 200 ------- 2 0.0 3.0 14 26 + 0.138 0 1 tcp 200 ------- 2 0.0 3.0 15 27 d 0.138 0 1 tcp 200 ------- 2 0.0 3.0 15 27 At time 0.136933 an acknowledgement of flow tcp0 (host 3 -> host 0) arrives at host 0. That gives tcp0 permission to send two packets. At that same time 0.136933 both data packets are made available to the output buffer in host 0 toward router 1. However: The first of the two data packetsc (sequence number 12) fits in the buffere, but fills that buffer. That output buffer then is full, so that the next packet (sequence number 13) is dropped. All this happens at the same time: 0.136933. At time 0.138 another packet of that flow is also dropped. The two dropped data packets have sequence numbers 13 and 15. In-between, the packet with sequence number 14 is not dropped. A while later: r 0.179547 1 0 ack 40 ------- 2 3.0 0.0 12 54 + 0.179547 0 1 tcp 200 ---A--- 2 0.0 3.0 13 64 - 0.179547 0 1 tcp 200 ---A--- 2 0.0 3.0 13 64 At time 0.179547 tcp0 retransmits the packet that was dropped at time 0.136933. It gets the same sequence number in the flow (13), but a new global sequence number (64). I assume that the A means this is a retransmitted packet. (Needs checking: anybody?) It seems the retranmission is triggered by a ``third duplicate acknowledgement''. That would indicate this is a Reno or newReno flow, not a Tahoe flow. Mr Raizada, are you sure this is a Tahoe flow? Please check: between time 0.136933 and time 0.179547, host 3 sends a number of acknowledgement packets that acknowledge packet 12: Packets (globally) 34, 35, 53, 54, 55, 56, 57, 58, 59, 60, 68. Packet 34 is an ``ordinary'' acknowledgement (it acknowledges arrival of sequence number 12). All other ones are duplicate acknowledgements. Since in this simulation run no acknowledgement packets get dropped, the source of tcp0 counts packet 34 as a good acknowledgement, and packets 35, 53, 54, etc as duplicate acknowledgements. Hence, arrival of packet 54 at host 0 triggers re-transmission of the packet with sequence number 13. In more complicated simulations (e.g. bidirectional traffic) acknowledgements, including duplicate acknowledgements, can get dropped. This makes things really complicated! Finally, at time 0.191747 the retransmitted packet (sequence number 13) arrives in host 3. Host 3 sends an acknowledgement for packet sequence number 14: Sequence number 14 had arrived, but sequence number 15 was dropped. At that point host 3 already has the packets with sequence numbers 14, 16, 17, 18, 19, 20, 22, 24, 26, 27. So packets 15, 21, 23, 25 got lost. (Check this!). --- We see that the ``trace-file'': (1) Contains lots of interesting information, (2) Is hard to read, (3) Has the potential for enormous output files! --- Mr Raizada wrote a program that takes an out.tr file and gives the same information in more human-friendly form. I call the executable of this program ``readable'' and I now copy readable to exec. Result: maan-162 exec>: ls -l total 14696 -rw-r--r-- 1 ott 30 3445 Sep 1 16:07 2tcp_1node.tcl -rw-r--r-- 1 ott 30 96661 Sep 1 16:13 first -rw-r--r-- 1 ott 30 96661 Sep 2 12:52 first.nam -rwxr-xr-x 1 ott 30 2546856 Aug 30 14:25 nam -rwxr-xr-x 1 ott 30 4728572 Aug 30 14:19 ns -rw-r--r-- 1 ott 30 37469 Sep 1 16:13 out.tr -rwxr-xr-x 1 ott 30 11252 Sep 2 15:07 readable Next, I execute readable . It has the weakness that names of input file, output file are hardwired in the program: (output of ls -l after executing readable ): total 14754 -rw-r--r-- 1 ott 30 3445 Sep 1 16:07 2tcp_1node.tcl -rw-r--r-- 1 ott 30 96661 Sep 1 16:13 first -rw-r--r-- 1 ott 30 96661 Sep 2 12:52 first.nam -rwxr-xr-x 1 ott 30 2546856 Aug 30 14:25 nam -rwxr-xr-x 1 ott 30 4728572 Aug 30 14:19 ns -rw-r--r-- 1 ott 30 37469 Sep 1 16:13 out.tr -rwxr-xr-x 1 ott 30 11252 Sep 2 15:07 readable -rw-r--r-- 1 ott 30 29503 Sep 2 15:11 readfile.txt out.tr is the input file. readfile.txt is the output file. readfile.txt can be found on this website. Look at it: do you find it easier to read than out.tr ? But: It is not shorter! Check what out.tr and readfile.txt say about packet number 25. Problems to be solved: How do you use ns to obtain the ``goodput'' of a tcp flow as function of (say) bottleneck buffer size, if ``everything else'' is constant? Or as function of bottleneck link speed, if ``everything else'' is constant? Or as function of total propagation delay? Or ... .