MFLoodルーティングプロトコル(NS-2シミュレーション)
「NSとネットワークシミュレーション」の上のコードは、デバッグと修正を経て、一部追加されました.
mflood.h
mflood.cc
mflood-packet.h
mflood-seqtable.h
mflood-seqtable.cc
コンパイルで発生したエラー:
INITIALIZE THE LIST xListHead (_o17 cmd line 1) invoked from within"_o17 cmd port-dmux _o26" invoked from within"catch "$self cmd $args"ret" invoked from within"if [catch "$self cmd $args"ret] {set cls [$self info class]global errorInfoset savedInfo $errorInfoerror "error when calling class $cls: $args"$..." (procedure "_o17"line 2) (SplitObject unknown line 2) invoked from within"$agent port-dmux $dmux_" (procedure "_o14"line 11) (Node/MobileNode add-target-rtagent line 11) invoked from within"$self add-target-rtagent $agent $port" (procedure "_o14"line 28) (Node/MobileNode add-target line 28) invoked from within"$self add-target $agent $port" (procedure "_o14"line 15) (Node attach line 15) invoked from within"$node attach $ragent [Node set rtagent_port_]" (procedure "_o3"line 84) (Simulator create-wireless-node line 84) invoked from within"_o3 create-wireless-node" ("eval"body line 1) invoked from within"eval $self create-wireless-node $args" (procedure "_o3"line 23) (Simulator node line 23) invoked from within"$ns_ node" ("for"body line 3) invoked from within"for {set i 0} {$i<$val(nn)} {incr i} { puts "here 1"set nodes($i) [$ns_ node] puts "here 2"#$nodes($i) random-motion }" (file "mflood/test_mflood.tcl"line 40)num_nodes is set 3
元のmflood.ccファイルにコードを追加します.
mfloodルーティングプロトコルのtclテストスクリプト
その他のいくつかの設定参考書に記載されています.
mflood.h
#ifndef ns_mflood_h
#define ns_mflood_h
#include <sys/types.h>
#include <cmu-trace.h>
#include <priqueue.h>
#include "mflood-seqtable.h"
//#define NOW (Scheduler::instance().clock())
#define NETWORK_DIAMETER 30
#define FORWARD_DELAY 0.01
#define NO_DELAY -1.0
class MFlood:public Agent {
friend class MFlood_RTEntry;
public:
MFlood(nsaddr_t id);
void recv(Packet *p,Handler *);
protected:
int command (int,const char *const *);
inline int initialized(){return 1&&target_;}
void rt_resolve(Packet *p);
void forward(MFlood_RTEntry *rt,Packet *p,double delay);
nsaddr_t index_;
MFlood_RTable rtable_;
Trace *logtarget;
NsObject *uptarget_;
NsObject *port_dmux_ ;
private:
u_int32_t myseq_;
};
#endif
mflood.cc
#include "mflood.h"
#include "mflood-packet.h"
#include <cmu-trace.h>
#include <random.h>
int hdr_mflood::offset_;
static class MFloodHeaderClass:public PacketHeaderClass {
public:
MFloodHeaderClass():PacketHeaderClass("PacketHeader/MFlood",sizeof(hdr_mflood)) {
bind_offset(&hdr_mflood::offset_);
}
}class_mfloodhdr;
static class MFloodClass:public TclClass{
public:
MFloodClass():TclClass("Agent/MFlood"){}
TclObject *create(int argc,const char *const *argv) {
assert(argc==5);
return (new MFlood((nsaddr_t)atoi(argv[4])));
}
}class_rtProtoMFlood;
int MFlood::command(int argc,const char *const *argv) {
Tcl &tcl = Tcl::instance();
if(argc==2) {
if(strncasecmp(argv[1],"id",2)==0) {
tcl.resultf("%d",index_);
return TCL_OK;
}
else if (strcmp(argv[1],"uptarget")==0) {
if(uptarget_ !=0)
tcl.result(uptarget_->name());
return (TCL_OK);
}
/*else if(strcmp(argv[1],"port-dmux")==0) {
return (TCL_OK);
}*/
}else if(argc==3) {
if(strcmp(argv[1],"index_")==0){
index_ = atoi(argv[2]);
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;
}
else if (strcmp(argv[1],"uptarget")==0) {
if(*argv[2]=='0'){
target_=0;
return (TCL_OK);
}
uptarget_ =(NsObject*)TclObject::lookup(argv[2]);
if(uptarget_==0){
tcl.resultf("no such object %s",argv[2]);
return (TCL_ERROR);
}
return (TCL_OK);
}
else if(strcasecmp(argv[1],"port-dmux")==0) {
TclObject *obj;
port_dmux_ = (NsObject *)obj;
return (TCL_OK);
}
}
return Agent::command(argc,argv);
}
MFlood::MFlood(nsaddr_t id):Agent(PT_MFlood),port_dmux_(0){
index_ = id;
logtarget = 0;
myseq_ = 0;
}
// Route Handling Functions
void MFlood::rt_resolve(Packet *p) {
//struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
struct hdr_mflood *fh = HDR_MFLOOD(p);
MFlood_RTEntry *rt ;
rt = rtable_.rt_lookup(ih->saddr());
if(rt==NULL) {
rt = new MFlood_RTEntry(ih->saddr(),fh->seq_);
LIST_INSERT_HEAD(&rtable_.rthead,rt,rt_link);
forward(rt,p,FORWARD_DELAY);
}
else if(rt->isNewSeq(fh->seq_))
{
forward(rt,p,FORWARD_DELAY);
rt->addSeq(fh->seq_);
}
else {
drop(p,"LOWSEQ");
}
}
void MFlood::recv(Packet *p,Handler *) {
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih =HDR_IP(p);
struct hdr_mflood *fh=HDR_MFLOOD(p);
assert(initialized());
if((ih->saddr()==index_) &&(ch->num_forwards()==0)) {
ch->size() += IP_HDR_LEN;
ih->ttl_ = NETWORK_DIAMETER;
fh->seq_ = myseq_++;
forward((MFlood_RTEntry*)1,p,0);
return ;
}
else if (ih->saddr() == index_) {
drop(p,DROP_RTR_ROUTE_LOOP);
return ;
}
else {
if(--ih->ttl_==0){
drop(p,DROP_RTR_TTL);
return ;
}
}
rt_resolve(p);
}
void MFlood::forward(MFlood_RTEntry *rt,Packet *p,double delay) {
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
assert(ih->ttl_ > 0);
assert(rt!=0);
ch->next_hop_ = -1;
ch->addr_type() = NS_AF_INET;
ch ->direction() = hdr_cmn::DOWN;
if(delay > 0.0) {
Scheduler::instance().schedule(target_,p,Random::uniform(delay*2));
}
else {
Scheduler::instance().schedule(target_,p,0);
}
}
mflood-packet.h
#ifndef mflood_packet_h
#define mflood_packet_h
#define HDR_MFLOOD(p) ((struct hdr_mflood*)hdr_mflood::access(p))
struct hdr_mflood {
u_int32_t seq_;
static int offset_;
inline static int& offset() {
return offset_;
}
inline static hdr_mflood *access(const Packet *p) {
return (hdr_mflood*)p->access(offset_);
}
};
#endif
mflood-seqtable.h
#ifndef mflood_seqtable_h
#define mflood_seqtable_h
#include <assert.h>
#include <sys/types.h>
#include <config.h>
#include <lib/bsd-list.h>
#include <scheduler.h>
//#define INFINITY 0xff
#define RTF_DOWN 0
#define RTF_UP 1
#define REM_SEQ_COUNT 1000
//Route Table Entry
class MFlood_RTEntry {
friend class MFlood_RTable;
friend class MFlood;
public:
MFlood_RTEntry();
MFlood_RTEntry(nsaddr_t src,u_int32_t seq);
bool isNewSeq(u_int32_t seq);
void addSeq(u_int32_t seq);
protected:
LIST_ENTRY(MFlood_RTEntry) rt_link;
nsaddr_t src_;
u_int32_t rt_seqnos[REM_SEQ_COUNT];
u_int32_t max_seqno;
u_int32_t min_seqno;
u_int16_t seq_it; // seqno's iterator
};
// The Routing Table
class MFlood_RTable {
friend class MFlood;
public:
MFlood_RTable() {LIST_INIT(&rthead);} // initial the routing table
void rt_delete(nsaddr_t id);
MFlood_RTEntry *rt_lookup(nsaddr_t id);
void rt_print();
private:
LIST_HEAD(,MFlood_RTEntry) rthead;
};
#endif
mflood-seqtable.cc
#include "mflood-seqtable.h"
MFlood_RTEntry::MFlood_RTEntry() {
src_= 0;
for(int i=0; i<REM_SEQ_COUNT; i++)
rt_seqnos[i] = 0xffffffff;
max_seqno = 0;
min_seqno = 0;
seq_it = 0;
}
// The routing table
MFlood_RTEntry::MFlood_RTEntry(nsaddr_t src,u_int32_t seq){
src_ = src;
for(int i=0; i < REM_SEQ_COUNT;i++)
rt_seqnos[i] = 0xffffffff;
rt_seqnos[0] = seq;
max_seqno = seq ;
min_seqno = 0;
seq_it = 1;
}
bool MFlood_RTEntry::isNewSeq(u_int32_t seq) {
if(seq > max_seqno)
return true;
//
if(seq < min_seqno)
return false;
for(int i=0;i<REM_SEQ_COUNT;i++)
if(seq == rt_seqnos[i])
return false;
return true ;
}
void MFlood_RTEntry::addSeq(u_int32_t seq) {
//u_int16_t min_it = 0;
if(seq < min_seqno)
return ;
if(seq > max_seqno)
max_seqno = seq;
rt_seqnos[seq_it++] = seq;
seq_it %= REM_SEQ_COUNT;
min_seqno = 0xffffffff;
for(int i=0 ; i < REM_SEQ_COUNT ; i++)
if(min_seqno > rt_seqnos[i])
min_seqno = rt_seqnos[i];
}
MFlood_RTEntry *MFlood_RTable::rt_lookup(nsaddr_t id){
MFlood_RTEntry *rt = rthead.lh_first;
for(;rt; rt = rt->rt_link.le_next)
{
if(rt->src_ == id)
break ;
}
return rt;
}
void MFlood_RTable::rt_delete(nsaddr_t id) {
MFlood_RTEntry *rt = rt_lookup(id);
if(rt){
LIST_REMOVE(rt,rt_link);
delete rt;
}
}
void MFlood_RTable::rt_print() {
MFlood_RTEntry *rt = rthead.lh_first;
for(;rt;rt=rt->rt_link.le_next) {
// printf("index:%d,seq:%d
",rt->src_,rt->max_seqno);
}
return ;
}
コンパイルで発生したエラー:
INITIALIZE THE LIST xListHead (_o17 cmd line 1) invoked from within"_o17 cmd port-dmux _o26" invoked from within"catch "$self cmd $args"ret" invoked from within"if [catch "$self cmd $args"ret] {set cls [$self info class]global errorInfoset savedInfo $errorInfoerror "error when calling class $cls: $args"$..." (procedure "_o17"line 2) (SplitObject unknown line 2) invoked from within"$agent port-dmux $dmux_" (procedure "_o14"line 11) (Node/MobileNode add-target-rtagent line 11) invoked from within"$self add-target-rtagent $agent $port" (procedure "_o14"line 28) (Node/MobileNode add-target line 28) invoked from within"$self add-target $agent $port" (procedure "_o14"line 15) (Node attach line 15) invoked from within"$node attach $ragent [Node set rtagent_port_]" (procedure "_o3"line 84) (Simulator create-wireless-node line 84) invoked from within"_o3 create-wireless-node" ("eval"body line 1) invoked from within"eval $self create-wireless-node $args" (procedure "_o3"line 23) (Simulator node line 23) invoked from within"$ns_ node" ("for"body line 3) invoked from within"for {set i 0} {$i<$val(nn)} {incr i} { puts "here 1"set nodes($i) [$ns_ node] puts "here 2"#$nodes($i) random-motion }" (file "mflood/test_mflood.tcl"line 40)num_nodes is set 3
元のmflood.ccファイルにコードを追加します.
mfloodルーティングプロトコルのtclテストスクリプト
#parameters
set val(ifqlen) 50
set val(nn) 3
set val(rp) MFlood
set val(chan) Channel/WirelessChannel
set val(prop) Propagation/TwoRayGround
set val(netif) Phy/WirelessPhy
set val(mac) Mac/802_11
set val(ifq) Queue/DropTail/PriQueue
set val(ll) LL
set val(ant) Antenna/OmniAntenna
set val(stop) 200
set ns_ [new Simulator]
set tracefd [open mflood.tr w]
$ns_ trace-all $tracefd
# topology
set topo [new Topography]
$topo load_flatgrid 1000 500
create-god $val(nn)
set channel [new Channel/WirelessChannel]
$ns_ node-config -adhocRouting $val(rp) \
-llType $val(ll) \
-macType $val(mac) \
-ifqType $val(ifq) \
-ifqLen $val(ifqlen)) \
-antType $val(ant) \
-propType $val(prop) \
-phyType $val(netif) \
-channel $channel \
-topoInstance $topo \
-agentTrace ON \
-routerTrace ON \
-macTrace OFF \
-movementTrace ON
for {set i 0 } { $i < $val(nn)} { incr i} {
set nodes($i) [$ns_ node]
$nodes($i) random-motion 0
}
$nodes(0) set X_ 100.0
$nodes(0) set Y_ 200.0
$nodes(0) set Z_ 0.0
$nodes(1) set X_ 250.0
$nodes(1) set Y_ 200.0
$nodes(1) set X_ 0.0
$nodes(2) set X_ 400.0
$nodes(2) set Y_ 200.0
$nodes(2) set Z_ 0.0
set udp_(0) [new Agent/UDP]
$ns_ attach-agent $nodes(0) $udp_(0)
set null_(0) [new Agent/Null]
$ns_ attach-agent $nodes(2) $null_(0)
$ns_ connect $udp_(0) $null_(0)
set cbr_(0) [new Application/Traffic/CBR]
$cbr_(0) set packetSize_ 512
$cbr_(0) set interval_ 4.0
$cbr_(0) set random_ 1
$cbr_(0) set maxpkts 1000
$cbr_(0) attach-agent $udp_(0)
$ns_ at 10.0 "$cbr_(0) start"
for {set i 0} { $i < $val(nn)} {incr i} {
$ns_ at $val(stop) "$nodes($i) reset"
}
$ns_ at $val(stop) "stop"
$ns_ at $val(stop) "puts \"NS EXISTING...\";$ns_ halt"
proc stop {} {
global ns_ tracefd
$ns_ flush-trace
close $tracefd
}
puts "Starting Simulation"
$ns_ run
その他のいくつかの設定参考書に記載されています.