NS2.35下添加新的无线路由协议要点

1、在NS2下添加路由协议,主要是参照已有的像AODV、DSDV等路由协议,当然如果不想添加可以直接在这两种协议上进行修改。总而言之,我们要抓住一点,我们所添加的协议是在一个节点上,只要我们在一个节点上添加成功了,那么其他的节点都是一样的,所以我们在编写协议的时候主要抓住节点的收和发以及转发这3个基本点去编写,无论协议有多复杂,还是离不开这3点。接收的时候有来自上层TCP/UDP传下来的,还有是从下层传上来的;

在ns2中添加协议,主要是包的添加,以及在哪些地方需要去进行注册以至于我们的新协议可以和已经有的AODV一样;

例如我们可以在节点配置的时候

node-config  -adhcoRouting  New_Protocol

......

.....

可以直接调用我们的新协议;

主要添加的文件为:

ns-2.35/tcl/lib/ns-default.tcl

这个tcl文件主要作用是当我们在c++中绑定了和otcl的变量以后,在它里面进行初始化

ns-2.35/tcl/lib/ns-packet.tcl

这个tcl文件中有如下的一个用来激活我们的包头,在此文件中添加我们的PacketHeader/NewHeader中的NewHeader来完成注册;

set protolist {
# Common:
	Common 
	Flags
	IP 	# IP
# Routing Protocols:
	NV 	# NixVector classifier for stateless routing 
	rtProtoDV 	# distance vector routing protocol
	rtProtoLS 	# link state routing protocol
	SR 	# source routing, dsr/hdr_sr.cc
	Src_rt 	# source routing, src_rtg/hdr_src.cc
# Routers:
	LDP 	# mpls/ldp.cc
	MPLS 	# MPLS, MultiProtocol Label Switching

问题:NewHeader注册这个和哪里对应?和在packet.h中定义的包的类型,名字时候需要一致?

其实这个注册的NewHeader是与下面的SimpleHeaderClass中的SIMPLE是对应一致的,因为它就是一个OTCL对象,方便我们在TCL代码中去加入或者删除不需要的包头

1、NewHeader这个注册的TCL包头和其他在Packet建立的类型没有任何关系,所以名字不一样也是可以的;

2、值得注意的是:

static class SimpleHeaderClass:public PacketHeaderClass{
public:
	SimpleHeaderClass():PacketHeaderClass("PacketHeader/SIMPLE",sizeof(hdr_simple_pkt)){
		bind_offset(&hdr_simple_pkt::offset_);
	}
}class_rtProtoSimple_hdr;
我们必须而且只能在构造函数中绑定offset,这样由包头管理器可以定位到此包头的位置,在tcl中,我们也用NewHeader可以增加和删除包,如:

remove-packet-header AODV ARP

注册,定义是为了在TCL中使用更加方便

ns-2.35/tcl/lib/ns-agent.tcl

在这里面有一些agent的初始化以及过程的定义,我们可以在里面添加我们自己的过程;这个最终是要被source到ns-lib.tcl中的

ns-2.35/tcl/lib/ns-lib.tcl

当我们去添加无线路由协议的时候,我们要找到如下代码

Simulator instproc create-wireless-node args {
        $self instvar routingAgent_ wiredRouting_ propInstance_ llType_ \
	    macType_ ifqType_ ifqlen_ phyType_ chan antType_ \
	    energyModel_ initialEnergy_ txPower_ rxPower_ \
	    idlePower_ sleepPower_ sleepTime_ transitionPower_ transitionTime_ \
	    topoInstance_ level1_ level2_ inerrProc_ outerrProc_ FECProc_ rtAgentFunction_

	Simulator set IMEPFlag_ OFF

        # create node instance
        set node [eval $self create-node-instance $args]
        
        # basestation address setting
        if { [info exist wiredRouting_] && $wiredRouting_ == "ON" } {
		$node base-station [AddrParams addr2id [$node node-addr]]
    	}
        if {$rtAgentFunction_ != ""} {
		set ragent [$self $rtAgentFunction_ $node]
	} else {
		switch -exact $routingAgent_ {
		    DSDV {
			    set ragent [$self create-dsdv-agent $node]
		    }
		    DSR {
			    $self at 0.0 "$node start-dsr"
		    }
		    AODV {
		    		puts "aodv----------------------------------------"
			    set ragent [$self create-aodv-agent $node]
		    }
		    AOMDV {
			    set ragent [$self create-aomdv-agent $node]
		    }
		    MDART {
			    set ragent [$self create-mdart-agent $node]
		    }
                    PUMA {
                            set ragent [$self create-puma-agent $node]
                    }
		    TORA {
			    Simulator set IMEPFlag_ ON
			    set ragent [$self create-tora-agent $node]
		    }
		    DIFFUSION/RATE {
			    eval $node addr $args
			    set ragent [$self create-diffusion-rate-agent $node]
		    }
		    DIFFUSION/PROB {
			    eval $node addr $args
			    set ragent [$self create-diffusion-probability-agent $node]
		    }
		    Directed_Diffusion {
			    eval $node addr $args
			    set ragent [$self create-core-diffusion-rtg-agent $node]
		    }
		    FLOODING {
			    eval $node addr $args
			    set ragent [$self create-flooding-agent $node]
		    }
		    OMNIMCAST {
			    eval $node addr $args
			    set ragent [$self create-omnimcast-agent $node]
		    }
		    DumbAgent {
			    set ragent [$self create-dumb-agent $node]
		    }
		    ManualRtg {
			    set ragent [$self create-manual-rtg-agent $node]
		    }
		    Simple {
				
		    	    set ragent [$self create-simple-agent $node]
		    }
		    default {
			    eval $node addr $args
			    puts "Wrong node routing agent!"
			    exit
		    }
		}
	}
可以看到里面有AODV等等协议;可以按照上面的例子加入自己的协议;

Simulator instproc create-simple-agent { node} {
	set ragent [new Agent/Simple [$node node-addr] ]
	
	$self at 0.0 "$ragent start"
	$node set ragent_ $ragent
	return $ragent

}
加入自己的方法,按照已有的路由,不过其中的方法我们要在.cc中的command存在,否则报错。

ns-2.35/trace/cmu-trace.cc文件

加入自己的协议以后,我们更加关注的是trace文件以及输出格式,在此文件中实现了所有trace的格式

找到以下内容,我们可以添加自己的格式

void CMUTrace::format(Packet* p, const char *why)
{
	hdr_cmn *ch = HDR_CMN(p);
	int offset = 0;

	/*
	 * Log the MAC Header
	 */
	<span style="color:#ff0000;">format_mac_common(p, why, offset);</span>
//	cout<<ch->ptype()<<endl;
//	cout<< packet_info.name(76)<<endl;
	if (pt_->namchannel()) 
		nam_format(p, offset);
	offset = strlen(pt_->buffer());
		//insert myself
	switch(ch->ptype()) {
	case PT_MAC:
	case PT_SMAC:
		break;
	case PT_ARP:
		format_arp(p, offset);
		break;
	default:
		<span style="color:#ff0000;">format_ip(p, offset);</span>
		offset = strlen(pt_->buffer());
		switch(ch->ptype()) {
		case PT_AODV:
			format_aodv(p, offset);
			break;
		// AOMDV patch
		case PT_AOMDV:
			format_aomdv(p, offset);
			break;
		case PT_TORA:
                        format_tora(p, offset);
                        break;
                case PT_IMEP:
                        format_imep(p, offset);
                        break;
		case PT_DSR:
			format_dsr(p, offset);
			break;
		case PT_MESSAGE:
		case PT_UDP:
			format_msg(p, offset);
			break;
		case PT_TCP:
		case PT_ACK:
			format_tcp(p, offset);
			break;
		case PT_SCTP:
			/* Armando L. Caro Jr. <acaro@@cis,udel,edu> 6/5/2002
			 */
			format_sctp(p, offset);
			break;
		case PT_CBR:
			format_rtp(p, offset);
			break;
	        case PT_DIFF:
			break;
		case PT_GAF:
		case PT_PING:
			break;
		case PT_SIMPLE:
			format_simple(p,offset);
			break;
		default:

			if(pktTrc_ && pktTrc_->format_unknow(p, offset, pt_, newtrace_))
				break;

		/*<zheng: del -- there are many more new packet types added, like PT_EXP (poisson traffic belongs to this type)>
			fprintf(stderr, "%s - invalid packet type (%s).\n",
				__PRETTY_FUNCTION__, packet_info.name(ch->ptype()));
			exit(1);
		</zheng: del>*/
			break;		//zheng: add
		}
	}
}
可以在代码中看到AODV和以及其他的包格式,我们也将自己的添加进去,然后编写自己的format函数,值得一提的是,从代码中我们会发现,在代码中以及为我们添加了

format_mac_common以及format_ip函数,所以我们自己添加的协议会出现在其后;形成这种类型

s 12.000000000 _0_ RTR  --- 0 AODV 48 [0 0 0 0] ------- [0:255 -1:255 30 0] [0x2 1 2 [1 0] [0 6]] (REQUEST)


ns-2.35/common/packet.h

在这个包里我们进行包类别的定义以及名字的绑定;

static const packet_t PT_DCCP = 63;
static const packet_t PT_DCCP_REQ = 64;
static const packet_t PT_DCCP_RESP = 65;
static const packet_t PT_DCCP_ACK = 66;
static const packet_t PT_DCCP_DATA = 67;
static const packet_t PT_DCCP_DATAACK = 68;
static const packet_t PT_DCCP_CLOSE  = 69;
static const packet_t PT_DCCP_CLOSEREQ = 70;
static const packet_t PT_DCCP_RESET = 71;

        // M-DART packets
static const packet_t PT_MDART = 72;

static const packet_t PT_SIMPLE=73;
static const packet_t PT_LWB=74;
static const packet_t PT_TEST1=75;
static const packet_t PT_TEST2=76;	


        // insert new packet types here
static  packet_t PT_NTYPE = 77; // This MUST be the LAST one
这里注意最后一个不为const常量

class p_info {
public:
	p_info()
	{
		initName();
	}
	const char* name(packet_t p) const { 
		if ( p <= p_info::nPkt_ ) return name_[p];
		return 0;
	}
	static bool data_packet(packet_t type) {
		return ( (type) == PT_TCP || \
		         (type) == PT_TELNET || \
		         (type) == PT_CBR || \
		         (type) == PT_AUDIO || \
		         (type) == PT_VIDEO || \
		         (type) == PT_ACK || \
		         (type) == PT_SCTP || \
		         (type) == PT_SCTP_APP1 || \
		         (type) == PT_HDLC \
		        );
	}
	static packetClass classify(packet_t type) {		
		if (type == PT_DSR || 
		    type == PT_MESSAGE || 
		    type == PT_TORA ||
		    type == PT_PUMA ||
		    type == PT_AODV ||
		    type == PT_MDART ||
		    type == PT_SIMPLE)
			return ROUTING;		
		if (type == PT_TCP || 
		    type == PT_TELNET || 
		    type == PT_CBR || 
		    type == PT_AUDIO || 
		    type == PT_VIDEO || 
		    type == PT_ACK || 
		    type == PT_SCTP || 
		    type == PT_SCTP_APP1 || 
		    type == PT_HDLC)
			return DATApkt;
		if (pc_)
			return pc_->classify(type);
		return UNCLASSIFIED;
	}
	static void addPacketClassifier(PacketClassifier *pc)
	{
		if(!pc)
		        return;
		pc->setNext(pc_);
		pc_ = pc;
	}       
	static void initName()
	{
		if(nPkt_ >= PT_NTYPE+1)
		        return;
		char **nameNew = new char*[PT_NTYPE+1];
		for(unsigned int i = (unsigned int)PT_SMAC+1; i < nPkt_; i++)
		{
		        nameNew[i] = name_[i];
		}
		if(!nPkt_)
		        delete [] name_;
		name_ = nameNew;
		nPkt_ = PT_NTYPE+1;
		
		
		name_[PT_TEST1]="test1";
		name_[PT_TEST2]="test2";
		name_[PT_TCP]= "tcp";
		name_[PT_UDP]= "udp";
		name_[PT_CBR]= "cbr";
		name_[PT_AUDIO]= "audio";
		name_[PT_VIDEO]= "video";
		name_[PT_ACK]= "ack";
		name_[PT_START]= "start";
		name_[PT_STOP]= "stop";
		name_[PT_PRUNE]= "prune";
		name_[PT_GRAFT]= "graft";
		name_[PT_GRAFTACK]= "graftAck";
		name_[PT_JOIN]= "join";
		name_[PT_ASSERT]= "assert";
		name_[PT_MESSAGE]= "message";
		name_[PT_RTCP]= "rtcp";
		name_[PT_RTP]= "rtp";
		name_[PT_RTPROTO_DV]= "rtProtoDV";
		name_[PT_CtrMcast_Encap]= "CtrMcast_Encap";
		name_[PT_CtrMcast_Decap]= "CtrMcast_Decap";
		name_[PT_SRM]= "SRM";
	
		name_[PT_REQUEST]= "sa_req";	
		name_[PT_ACCEPT]= "sa_accept";
		name_[PT_CONFIRM]= "sa_conf";
		name_[PT_TEARDOWN]= "sa_teardown";
		name_[PT_LIVE]= "live"; 
		name_[PT_REJECT]= "sa_reject";
	
		name_[PT_TELNET]= "telnet";
		name_[PT_FTP]= "ftp";
		name_[PT_PARETO]= "pareto";
		name_[PT_EXP]= "exp";
		name_[PT_INVAL]= "httpInval";
		name_[PT_HTTP]= "http";
		name_[PT_ENCAPSULATED]= "encap";
		name_[PT_MFTP]= "mftp";
		name_[PT_ARP]= "ARP";
		name_[PT_MAC]= "MAC";
		name_[PT_TORA]= "TORA";
		name_[PT_DSR]= "DSR";
		name_[PT_AODV]= "AODV";
		name_[PT_MDART]= "MDART";
		name_[PT_IMEP]= "IMEP";
加入对应的名字

经过以上添加,便可以类似AODV一样做为无线路由算法添加到ns2中

tips:

添加新的协议,其实有一个基本的死框架,我们按照框架写完后,再进行自己协议的编写。

死框架:

1、申明一个继承了Agent类的子类,实现其中的recv()方法,其他是自己实现的函数

2、利用TclClass进行C++与OTCL进行绑定

3、申明一个包类型

4、将包类型的C++与OTCL进行绑定,利用PacketHeaderClass 类来实现

5、注册包类型

以上5个步骤是一个死框架,其它我们需要的时候往里加即可;







  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值