Adding your own protocol module in NS2 is generally a few steps:
(1) Adding a protocol class
(2) Define Protocol packet header structure
(3) Compile code
In fact, there is already a ping protocol in the ns3.35 version, this step is just to understand the general steps of NS2 Add protocol.
1, in the PING protocol, you need to define your own control group, so first you need to define the ping packet header structure in the Ping.h header file, the C + + code is as follows:
Define your own control groupings in the PING protocol
struct Hdr_ping {
char ret; 0: From sender to receiver, 1: from receiver to Sender
Double send_time; Send time, in order to calculate the RTT
};
Class Pingagent:public Agent {
Public
Pingagent ();
int command (int argc, const char*const* argv);
void Recv (packet*, handler*);
Protected
int off_ping_;
};
2, Ping needs to be accepted by NS-2 and can be used in the OTCL code, you need to define the following code in ping.cc:
Static class Pingheaderclass:public Packetheaderclass {
Public
Pingheaderclass (): Packetheaderclass ("packetheader/ping",
sizeof (hdr_ping)) {}
} CLASS_PINGHDR;
This code implements the Pinghead/ping class in OTCL with the hdr_ping in C + +, so the defined packet header is ping.
2, in the ~NS/TCL/LIB/NS-PACKET.TCL contains all the implemented protocol packet header names in the system, we also need to add the name of the Baotou Ping.
Foreach {
IVS
Qs
...
Ping
}
3. To create a ping group, you need to define the grouping type of the ping. You need to modify the Ns/common/packet.h file: First add the package type in Emun packet: pt_ping;
Enum packet_t {
PT_TCP,
PT_UDP,
...
Pt_ping
}
The name of the new package type is then defined in the class P_info constructor:
Class P_info {
Public:
P_info {
Name_[pt_tcp]= "TCP";
......
name_[pt_piing]= "Ping";
}
......
}
4, need to inherit a Pingclass class from TCLCL, its constructor by calling the base class constructor "Tclclass (" agent/ping ")" to specify its corresponding OTCL object for agent/ping, which is actually doing the registration work, Defined in ping.cc:
Static class Pingclass:public Tclclass {
Public
Pingclass (): Tclclass ("Agent/ping") {}
tclobject* Create (int, const char*const*) {
Return (new Pingagent ());
}
} class_ping;
OTCL Code:
Set p0 [New Agent/ping]
$ns attach-agent $n 0 $p 0
When the set p0 [new Agent/ping] is executed, the parent class's constructor (the Init method) is called, and the parent class Splitobject calls the Create-shadow method to enlist Otcl object P0 and the created C + + object class_ping relationship. Call tclobject* Create (int, const char*const*) According to the registration relationship and return the object pointer: return (new Pingagent ());
5. In the Pingagent constructor, you need to pass the newly created grouping type to the constructor of the agent class, because the constructor for the Pingagent parent class requires a custom grouping type as a parameter. The binding of member variables between C + + and OTCL is implemented in the Pingagent constructor.
Pingagent::P ingagent (): Agent (pt_ping)
{
Bind ("Packetsize_", &size_);
Bind ("Off_ping_", &off_ping_);
}
After a variable is bound, the member variables Packetsize_ and off_ping_ of the Agent/ping class object p0 are always consistent with the member variables of the C + + object. In order to initialize these variables, you need to add the following code to the ~NS/TCL/LIB/NS-DEFAULT.TCL:
Agent/ping Set PacketSize 0
Agent/ping Set Off_ping_ 0
NS-DEFAULT.TCL This file was executed before the Tcl script was run, so the variable was initialized when the object was created and the variable was bound.
6. When executing
$ns at 0.2 "$p 0 send"
Pointers to C + + objects call the command function according to the name of the procedure function, as follows:
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*) pkt->access (off_ping_);
Set the ' RET ' field to 0, so the receiving node knows
That it had 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 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));
}
6, after the completion of the Ping protocol definition and implementation, put PING.HH and ping.cc under ~ns/ping, and then recompile NS-2, the PING protocol embedded in the NS-2 code, we need to modify the ~ns/makefile file.
In Makefile's OBJ_CC, add the following code: PING/PING.O
Under the NS directory: make clean and make to complete the compilation.
7, the RECV function code in ping.cc is as follows:
void Pingagent::recv (packet* pkt, handler*)
{
Access the IP header for the received packet:
hdr_ip* Hdrip = (hdr_ip*) pkt->access (OFF_IP_);
Access the Ping header for the received packet:
hdr_ping* HDR = (hdr_ping*) pkt->access (off_ping_);
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*) pktret->access (off_ping_);
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} '
Have to is 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_ >> address::instance (). NODESHIFT_[1],
(Scheduler::instance (). Clock ()-hdr->send_time) * 1000);
tcl& tcl = Tcl::instance ();
Tcl.eval (out);
Discard the packet
Packet::free (PKT);
}
}
8. TCL test script as follows:
#Create a Simulator object
Set NS [New Simulator]
#Open A trace file
Set NF [Open Out.nam W]
$ns Namtrace-all $NF
#Define a ' finish ' procedure
Proc Finish {} {
Global NS NF
$ns Flush-trace
Close $NF
exec Nam Out.nam &
Exit 0
}
#Create three nodes
Set n0 [$ns node]
Set n1 [$ns node]
Set N2 [$ns node]
#Connect the nodes with the links
$ns duplex-link $n 0 $n 1 1Mb 10ms droptail
$ns duplex-link $n 1 $n 2 1Mb 10ms droptail
#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-ping agents and attach them to the nodes N0 and N2
Set p0 [New Agent/ping]
$ns attach-agent $n 0 $p 0
Set P1 [New Agent/ping]
$ns attach-agent $n 2 $p 1
#Connect the Agents
$ns Connect $p 0 $p 1
#Schedule Events
$ns at 0.2 "$p 0 send"
$ns at 0.4 "$p 1 Send"
$ns at 0.6 "$p 0 Send"
$ns at 0.6 "$p 1 Send"
$ns at 1.0 "Finish"
#Run the simulation
$ns Run
Http://www.cnblogs.com/ManMonth/archive/2011/03/15/1985518.html
To add a protocol ping to the NS2