#百思论坛整理ns下开发新协议.docx
《#百思论坛整理ns下开发新协议.docx》由会员分享,可在线阅读,更多相关《#百思论坛整理ns下开发新协议.docx(13页珍藏版)》请在冰豆网上搜索。
#百思论坛整理ns下开发新协议
最近正在研究怎样把自己新写的协议添加到NS2中去,正好借鉴了一些朋友的文章,现在整理下来,以便以后参考,也希望能给广大博友一些方便。
step1:
比如我们新建的协议名字就叫做protoname,以ns2.27平台为例,我们在ns2.27目录下建立一个protoname目录。
此目录包含protoname.h,protoname.cc,protoname_pkt.h,protoname_rtable.h,protoname_rtable.cc五个文件。
其中五个文件的具体功能和作用如下:
(1)protoname.h定义必要的计时器和路由代理
(2)protoname.cc执行计时器、路由代理和Tcl文件
(3)protoname_pkt.h声明protoname路由协议需要在无线自组网节点交换的数据包
(4)protoname_rtable.h声明我们自己的路由选择表
(5)protoname_rtable.cc执行路由选择表
step2:
相应文件的代码
(1)protoname.h
#ifndef__protoname_h__
#define__protoname_h__
//下面包含一些需要的头文件
#include"protoname_pkt.h"//数据包报头
#include"protoname_rtable.h"
#include //代理基本类
#include//数据包类
#include//跟踪类,用于在跟踪文件里记录输出的仿真结果
#include//计时器基本类,创建我们自定义的计时器
#include//随机类,用于产生伪随机数
#include//端口分类器类,用于淘汰向上层传输的数据包
#include
#include"arp.h"
#include"ll.h"
#include"mac.h"
#include"ip.h"
#include"delay.h"
#defineCURRENT_TIMEScheduler:
:
instance().clock()//定义了一个用于得到当前仿真时间的宏
//通过一个调度类的实例完成
#defineJITTER(Random:
:
uniform()*0.5)//在0-0.5之间去随机数作为发送数据的延迟时间
classProtoname;//forwarddeclaration
/*Timers*/ //自定义计时器发送定时的控制包
classProtoname_PktTimer:
publicTimerHandler{
public:
Protoname_PktTimer(Protoname*agent):
TimerHandler(){
agent_=agent;
}
protected:
Protoname*agent_;
virtualvoidexpire(Event*e);
};
/*Agent*///定义Protoname类
classProtoname:
publicAgent{
/*Friends*/
friendclassProtoname_PktTimer;
/*Privatemembers*///封装了自身的地址、内状态、路由表、可变的Tcl
//以及一个负责指定输出数量的计数器
nsaddr_tra_addr_;
//protoname_statestate_;
protoname_rtablertable_;
intaccesible_var_;//用来读取Tcl代码或脚本语言
u_int8_tseq_num_;
protected:
MobileNode*node_;
PortClassifier*dmux_;//Forpassingpacketsuptoagents.端口分类器
Trace*logtarget_;//Forlogging.跟踪器
Protoname_PktTimerpkt_timer_;//Timerforsendingpackets.自定义计时器
//内部属性
inlinensaddr_t&ra_addr(){returnra_addr_;}
//inlineprotoname_state&state(){returnstate_;}
inlineint&accessible_var(){returnaccesible_var_;}
voidforward_data(Packet*);//数据包被正确传输的目的地
voidrecv_protoname_pkt(Packet*);
voidsend_protoname_pkt();
voidreset_protoname_pkt_timer();
public:
Protoname(nsaddr_t);
intcommand(int,constchar*const*);
voidrecv(Packet*,Handler*);
//voidmac_failed(Packet*);
};
#endif
(2)protoname.cc
#include"protoname.h"
#include"protoname_pkt.h"
#include
#include
#include
inthdr_protoname_pkt:
:
offset_;
staticclassProtonameHeaderClass:
publicPacketHeaderClass{
public:
ProtonameHeaderClass():
PacketHeaderClass("PacketHeader/Protoname",sizeof(hdr_protoname_pkt)){
bind_offset(&hdr_protoname_pkt:
:
offset_);
}
}class_rtProtoProtoname_hdr;
staticclassProtonameClass:
publicTclClass{
public:
ProtonameClass():
TclClass("Agent/Protoname"){}
TclObject*create(intargc,constchar*const*argv){
assert(argc==5);
return(newProtoname((nsaddr_t)Address:
:
instance().str2addr(argv[4])));
}
}class_rtProtoProtoname;
void
Protoname_PktTimer:
:
expire(Event*e){
agent_->send_protoname_pkt();
agent_->reset_protoname_pkt_timer();
}
Protoname:
:
Protoname(nsaddr_tid):
Agent(PT_PROTONAME),pkt_timer_(this){
bind_bool("accesible_var_",&accesible_var_);
ra_addr_=id;
node_=(MobileNode*)Node:
:
get_node_by_address(id);
}
int
Protoname:
:
command(intargc,constchar*const*argv){
if(argc==2){
if(strcasecmp(argv[1],"start")==0){
pkt_timer_.resched(0.0);
returnTCL_OK;
}
elseif(strcasecmp(argv[1],"print_rtable")==0){
if(logtarget_!
=0){
sprintf(logtarget_->pt_->buffer(),"P%f_%d_RoutingTable",CURRENT_TIME,ra_addr());
logtarget_->pt_->dump();
rtable_.print(logtarget_);
}
else{
fprintf(stdout,"%f_%d_Ifyouwanttoprintthisroutingtable"
"youmustcreateatracefileinyourtclscript",CURRENT_TIME,ra_addr());
}
returnTCL_OK;
}
}
elseif(argc==3){
//Obtainscorrespondingdmuxtocarrypacketstoupperlayers
if(strcmp(argv[1],"port-dmux")==0){
dmux_=(PortClassifier*)TclObject:
:
lookup(argv[2]);
if(dmux_==0){
fprintf(stderr,"%s:
%slookupof%sfailed\n",__FILE__,argv[1],argv[2]);
returnTCL_ERROR;
}
returnTCL_OK;
}
//Obtainscorrespondingtracer
elseif(strcmp(argv[1],"log-target")==0||strcmp(argv[1],"tracetarget")==0){
logtarget_=(Trace*)TclObject:
:
lookup(argv[2]);
if(logtarget_==0)
returnTCL_ERROR;
returnTCL_OK;
}
}
//Passthecommandtothebaseclass
returnAgent:
:
command(argc,argv);
}
void
Protoname:
:
recv(Packet*p,Handler*h){
structhdr_cmn*ch=HDR_CMN(p);
structhdr_ip*ih=HDR_IP(p);
if(ih->saddr()==ra_addr()){
//Ifthereexistsaloop,mustdropthepacket
if(ch->num_forwards()>0){
drop(p,DROP_RTR_ROUTE_LOOP);
return;
}
//elseifthisisapacketIamoriginating,mustaddIPheader
elseif(ch->num_forwards()==0)
ch->size()+=IP_HDR_LEN;
}
//Ifitisaprotonamepacket,mustprocessit
if(ch->ptype()==PT_PROTONAME)
recv_protoname_pkt(p);
//Otherwise,mustforwardthepacket(unlessTTLhasreachedzero)
else{
ih->ttl_--;
if(ih->ttl_==0){
drop(p,DROP_RTR_TTL);
return;
}
forward_data(p);
}
}
void
Protoname:
:
recv_protoname_pkt(Packet*p){
structhdr_ip*ih=HDR_IP(p);
structhdr_protoname_pkt*ph=HDR_PROTONAME_PKT(p);
//AllroutingmessagesaresentfromandtoportRT_PORT,
//sowecheckit.
assert(ih->sport()==RT_PORT);
assert(ih->dport()==RT_PORT);
/*...processingofprotonamepacket...*/
//Releaseresources
Packet:
:
free(p);
}
void
Protoname:
:
send_protoname_pkt(){
Packet*p=allocpkt();
structhdr_cmn*ch=HDR_CMN(p);
structhdr_ip*ih=HDR_IP(p);
structhdr_protoname_pkt*ph=HDR_PROTONAME_PKT(p);
ph->pkt_src()=ra_addr();
ph->pkt_len()=7;
ph->pkt_seq_num()=seq_num_++;
ch->ptype()=PT_PROTONAME;
ch->direction()=hdr_cmn:
:
DOWN;
ch->size()=IP_HDR_LEN+ph->pkt_len();
ch->error()=0;
ch->next_hop()=IP_BROADCAST;
ch->addr_type()=NS_AF_INET;
ih->saddr()=ra_addr();
ih->daddr()=IP_BROADCAST;
ih->sport()=RT_PORT;
ih->dport()=RT_PORT;
ih->ttl()=IP_DEF_TTL;
Scheduler:
:
instance().schedule(target_,p,JITTER);
}
void
Protoname:
:
reset_protoname_pkt_timer(){
pkt_timer_.resched((double)5.0);
}
void
Protoname:
:
forward_data(Packet*p){
structhdr_cmn*ch=HDR_CMN(p);
structhdr_ip*ih=HDR_IP(p);
if(ch->direction()==hdr_cmn:
:
UP&&
((u_int32_t)ih->daddr()==IP_BROADCAST||ih->daddr()==ra_addr())){
dmux_->recv(p,0);
return;
}
else{
ch->direction()=hdr_cmn:
:
DOWN;
ch->addr_type()=NS_AF_INET;
if((u_int32_t)ih->daddr()==IP_BROADCAST)
ch->next_hop()=IP_BROADCAST;
else{
nsaddr_tnext_hop=rtable_.lookup(ih->daddr());
if(next_hop==IP_BROADCAST){
debug("%f:
Agent%dcannotforwardapacketdestinedto%d\n",
CURRENT_TIME,
ra_addr(),
ih->daddr());
drop(p,DROP_RTR_NO_ROUTE);
return;
}
else
ch->next_hop()=next_hop;
}
Scheduler:
:
instance().schedule(target_,p,0.0);
}
}
(3)protoname_pkt.h
#ifndef__protoname_pkt_h__
#define__protoname_pkt_h__
#include
#defineHDR_PROTONAME_PKT(p)hdr_protoname_pkt:
:
access(p)
structhdr_protoname_pkt{
nsaddr_tpkt_src_;//Nodewhichoriginatedthispacket
u_int16_tpkt_len_;//Packetlength(inbytes)
u_int8_tpkt_seq_num_;//Packetsequencenumber
inlinensaddr_t&pkt_src(){returnpkt_src_;}
inlineu_int16_t&pkt_len(){returnpkt_len_;}
inlineu_int8_t&pkt_seq_num(){returnpkt_seq_num_;}
staticintoffset_;
inlinestaticint&offset(){returnoffset_;}
inlinestatichdr_protoname_pkt*access(constPacket*p){
return(hdr_protoname_pkt*)p->access(offset_);
}
};
#endif
(4)protoname_rtable.h
#ifndef__protoname_rtable_h__
#define__protoname_rtable_h__
#include
#include
typedefstd:
:
maprtable_t;
classprotoname_rtable{
rtable_trt_;
public:
protoname_rtable();
voidprint(Trace*);
voidclear();
voidrm_entry(nsaddr_t);
voidadd_entry(nsaddr_t,nsaddr_t);
nsaddr_tlookup(nsaddr_t);
u_int32_tsize();
};
#endif
(5)protoname_rtable.cc
#i