This agreement creates five files: protoname. H, protoname. CC, protoname_pkt.h, proto_rtable.h, proto_rtable.cc
Step 1: create a data packet header for the Protocol.
1.1 declared in protoname_pkt.h.
# Ifndef _ protoname_pkt_h __
# DEFINE _ protoname_pkt_h __
# Include <packet. h>
# Define hdr_protoname_pkt (p) (hdr_protoname_pkt: Access (p ))
Struct hdr_protoname_pkt {
Nsaddr_t pkt_src _; // source node that generates data packets
U_int16_t pkt_len _; // data packet length (in bytes)
U_int8_t pkt_seq_num _; // data serial number
Inline nsaddr_t & pkt_src () {return pkt_src _;}
Inline u_int16_t & pkt_len () {return pkt_len _;}
Inline u_int8_t & pkt_seq_num () {return pkt_seq_num _;}
// Header access methods
Static int offset _; // required by packetheadermanager
Inline static Int & offset () {return offset _;}
Inline static hdr_protoname_pkt * access (const packet * P ){
Return (hdr_protoname_pkt *) P-> access (offset _);
}
};
# Endif
1.2 In protoname. CC, bind the data header to the Tcl interface,
Int hdr_protoname_pkt: Offset _;
Static class protonameheaderclass: Public packetheaderclass {
Public:
Protonameheaderclass (): packetheaderclass ("packetheader/protoname", sizeof (hdr_protoname_pkt )){
Bind_offset (& hdr_protoname_pkt: Offset _);
}
} Class_rtprotoprotoname_hdr;
Step 2: declare the protoname class and other classes in protoname. h.
# Ifndef _ protoname_h __
# DEFINE _ protoname_h __
# Include "protoname_pkt.h" // protoname/protoname_pkt.h defines our data Headers
# Include "protoname_rtable.h"
# Include <agent. h> // common/agent. h defines the agent base class
# Include <packet. h> // common/packet. h defines the packet class
# Include <trace. h> // trace/trace. h defines the trace class, which is used to input simulation results to the trace file.
# Include <timer-handler.h> // common/timer-handler.h defines the timerhandler base class, which we use to create objective timers
# Include <random. h> // tools/random. h defines the random class to generate pseudo-random numbers.
# Include <classifier/classifier-port.h> // classifier/classifier-port.h defines the protclassifier class, used to transmit packets to the top layer
# Define current_time Scheduler: instance (). Clock ()
# Define jitter (random: Uniform () * 0.5)
Typedef u_int8_t protoname_state;
Class protoname; // Forward Declaration
Class protoname_pkttimer: Public timerhandler {// declare the global Timer class
Public:
Protoname_pkttimer (protoname * agent): timerhandler (){
Agent _ = agent;
}
Protected:
Protoname * Agent _;
Virtual void expire (event * E );
};
Class protoname: public agent {// declare the protoname class
Friend class protoname_pkttimer;
Nsaddr_t ra_addr _;
Protoname_state State _;
Protoname_rtable rtable _;
Int accessible_var _;
U_int8_t seq_num _;
Protected:
Portclassifier * dmux _; // used to transmit data packets to the proxy.
Trace * logtarget _; // For logging
Protoname_pkttimer pkt_timer _; // timer for sending data packets
Inline nsaddr_t & ra_addr () {return ra_addr _;}
Inline protoname_state & State () {return state _;}
Inline Int & accessible_var () {return accessible_var _;}
Void forward_data (packet *);
Void recv_protoname_pkt (packet *);
Void send_protoname_pkt ();
Void reset_protoname_pkt_timer ();
Public:
Protoname (nsaddr_t );
Int command (INT, const char * const *);
Void Recv (packet *, Handler *);
};
# Endif
Step 3: bind the protoname class to OTCL in protoname. CC.
Static class protonameclass: Public tclclass {
Public:
Protonameclass (): tclclass ("agent/protoname "){}
Tclobject * Create (INT argc, const char * const * argv ){
Assert (argc = 5 );
Return (New protoname (nsaddr_t) Address: instance (). str2addr (argv [4]);
}
} Class_rtprotoprotoname;
Step 4: bind the variable in protoname. CC and provide the C ++ variable for OTCL access.
Protoname: protoname (nsaddr_t ID): Agent (pt_protoname), pkt_timer _ (this) {// bind in the constructor
Bind_bool ("accessible_var _", & accessible_var _);
Ra_addr _ = ID;
}
Step 5: implement the Global Timer class function in protoname. CC. // Optional based on specific protocols
Void protoname_pkttimer: expire (event * E ){
Agent _-> send_protoname_pkt ();
Agent _-> reset_protoname_pkt_timer ();
}
Step 6: Provide C ++ control commands to OTCL in protoname. CC,
Int
Protoname: Command (INT argc, const char * const * argv ){
If (argc = 2) {// This function is inherited by our Proxy from the agent class.
If (strncasecmp (argv [1], "Start", 2) = 0 ){
Pkt_timer _. resched (0.0 );
Return tcl_ OK;
}
If (strncasecmp (argv [1], "print_rtable", 2) = 0 ){
If (logtarget _! = 0 ){
Sprintf (logtarget _-> Pt _-> buffer (), "P % F _ % d _ routing table", current_time, ra_addr ());
Logtarget _-> Pt _-> dump ();
Rtable _. Print (logtarget _);
}
Else {
Fprintf (stdout, "% F _ % d _ if you want to print this routing table you must create a trace"
"File in your TCL script", current_time, ra_addr ());
}
Return tcl_ OK;
}
}
Else if (argc = 3 ){
If (strcmp (argv [1], "port-dumx") = 0 ){
Dmux _ = (portclassifier *) tclobject: Lookup (argv [2]);
If (dmux _ = 0 ){
Fprintf (stderr, "% s: % s lookup of % s failed \ n" ,__ file __, argv [1], argv [2]);
Return tcl_error;
}
Return tcl_ OK;
}
Else if (strcmp (argv [1], "log-target") = 0 | strcmp (argv [1], "TraceTarget") = 0 ){
Logtarget _ = (trace *) tclobject: Lookup (argv [2]);
If (logtarget _ = 0)
Return tcl_error;
Return tcl_ OK;
}
}
Return agent: Command (argc, argv );
}
Step 7: process the received data in protoname. CC.
Void
Protoname: Recv (packet * P, Handler * h ){
Struct hdr_cen * Ch = hdr_cen (P );
Struct hdr_ip * ih = hdr_ip (P );
If (ih-> saddr () = ra_addr ()){
If (CH-> num_forwards ()> 0 ){
Drop (p, drop_rtr_route_loop );
Return;
}
Else if (CH-> num_forwards () = 0 ){
Ch-> size () + = ip_hdr_len;
}
}
If (CH-> ptype () = pt_protoname)
Recv_protoname_pkt (P );
Else {
Ih-> TTL _--;
If (ih-> TTL _ = 0 ){
Drop (p, drop_rtr_ttl );
Return;
}
Forward_data (P );
}
}
Declares packets in the NS-2.
A. Add pt_ptotoname to Enum packet_t of the enumerated type of common/packet. h.
B. Add name _ [pt_ptotoname] = "protoname" to the p_info class of common/packet. h"
Modify the Tcl Library:
A. Add a header and add protoname to foreach prot {} In Tcl/lib/ns-packet.tcl
B. Add the default value of protocol variable in Tcl/lib/ns-default.tcl
Agent/protoname set accessible_var _ true
C. Since this Protocol adds a process for creating a node, add the simulator instproc create-Wireless-node ARGs {} in the Tcl/lib/ns-lib.tcl
Protoname {set ragent [$ self create-protoname-agent $ node]}
Add in Tcl/lib/ns-lib.tcl
Simulator instproc create-protoname-agent {node }{
Set ragent [new agent/protoname [$ node-ADDR]
$ Self at 0.0 "$ ragent start"
$ Node set ragent _ $ ragent
Return $ ragent
}
Step 8: implement protocol-related functions in protoname. CC.
Functions to be implemented in this protocol include recv_protoname_pkt (), send_protoname_pkt (), reset_protoname_pkt_timer (), forward_data ().
Step 9: Create a route table for the Protocol. Declare the protname_rtable class in protoname_rtable.h and implement it in protoname_rtalbe.cc.
Add the following in makefile:
Protoname/protoname. O protoname/protoname_rtable.o \
Last./configure
Make clean
Make depend
Make