Ns Extend Xlming
Ns Extend Xlming
Ns Extend Xlming
NS2
Xu Leiming
CSCW Lab. at CS Dept., Tsinghua Univ.
mailto:[email protected]
June 1, 2001
Outline
Overview
An Example ---- Ping
Packet flow
Node models
Our research
Overview
New packet header
C++ code
Tcl code
Some necessary changes
Packet Header
Packet Header
New Packet Header
Create new header structure
Enable tracing support of new header
Create static class for OTcl linkage
(packet.h)
Enable new header in Otcl (tcl/lib/ns-
packet.tcl)
New Agent
Decide position in class hierarchy
Derive from a agent class
Link with a OTcl class
– TclClass TclObject
– TclObject::bind()
– Otcl --> c++: command() <otcl command>, tcl.result()
– c++ --> otcl: tcl.eval(“<otcl action>”)
PingAgent::PingAgent() : Agent(PT_PING)
{
bind("packetSize_", &size_);
}
int PingAgent::command(int argc, const char*const* argv)
{
if (argc == 2) {
if (strcmp(argv[1], "send") == 0) {
// Create a new packet
Packet* pkt = allocpkt();
// Access the Ping header for the new packet:
hdr_ping* hdr = hdr_ping::access(pkt);
// Set the 'ret' field to 0, so the receiving node knows
// that it has to generate an echo packet
hdr->ret = 0;
// Store the current time in the 'send_time' field
hdr->send_time = Scheduler::instance().clock();
// Send the packet
send(pkt, 0);
// return TCL_OK, so the calling function knows that the
// command has been processed
return (TCL_OK);
}
}
// If the command hasn't been processed by PingAgent()::command,
// call the command() function for the base class
return (Agent::command(argc, argv));
}
void PingAgent::recv(Packet* pkt, Handler*)
{
// Access the IP header for the received packet:
hdr_ip* hdrip = hdr_ip::access(pkt);
// Access the Ping header for the received packet:
hdr_ping* hdr = hdr_ping::access(pkt);
// Is the 'ret' field = 0 (i.e. the receiving node is being pinged)?
if (hdr->ret == 0) {
// Send an 'echo'. First save the old packet's send_time
double stime = hdr->send_time;
// Discard the packet
Packet::free(pkt);
// Create a new packet
Packet* pktret = allocpkt();
// Access the Ping header for the new packet:
hdr_ping* hdrret = hdr_ping::access(pktret);
// Set the 'ret' field to 1, so the receiver won't send another echo
hdrret->ret = 1;
// Set the send_time field to the correct value
hdrret->send_time = stime;
// Send the packet
send(pktret, 0);
} else {
// A packet was received. Use tcl.eval to call the Tcl
// interpreter with the ping results.
// Note: In the Tcl code, a procedure 'Agent/Ping recv {from rtt}'
// has to be defined which allows the user to react to the ping
// result.
char out[100];
// Prepare the output to the Tcl interpreter. Calculate the round
// trip time
sprintf(out, "%s recv %d %3.1f", name(),
hdrip->src_.addr_ >> Address::instance().NodeShift_[1],
(Scheduler::instance().clock()-hdr->send_time) * 1000);
Tcl& tcl = Tcl::instance();
tcl.eval(out);
// Discard the packet
Packet::free(pkt);
}
}
Ping.tcl
#Define a 'recv' function for the class 'Agent/Ping'
Agent/Ping instproc recv {from rtt} {
$self instvar node_
puts "node [$node_ id] received ping answer from \
$from with round-trip-time $rtt ms."
}
#Create two ping agents and attach them to the nodes n0 and n1
set p0 [new Agent/Ping]
$ns attach-agent $n0 $p0
set p1 [new Agent/Ping]
$ns attach-agent $n1 $p1
#Schedule events
$ns at 0.2 "$p0 send"
$ns at 0.4 "$p1 send"
$ns at 0.6 "$p0 send"
$ns at 0.6 "$p1 send"
$ns at 1.0 "finish"
name_[PT_PING]="Ping";
name_[PT_NTYPE]= "undefined";
}
.....
}
Necessary changes (cont.)
tcl/lib/ns-default.tcl
Agent/Ping set packetSize_ 64
tcl/lib/ns-packet.tcl
foreach prot {
AODV
ARP
aSRM
……
Ping
}{
add-packet-header $prot
}
Necessary changes (cont.)
Makefile
sessionhelper.o delaymodel.o srm-ssm.o \
srm-topo.o \
ping.o \
$(LIB_DIR)int.Vec.o $(LIB_DIR)int.RVec.o \
$(LIB_DIR)dmalloc_support.o \