2009-12-20

NS2 NSG2

http://sites.google.com/site/pengjungwu/nsg

在ns2.33中加入新的路由协议

http://hi.baidu.com/%D2%C1%C2%E4%B5%A4/blog/item/7352e9fa9b1b97d9b48f31f2.html

Abstract

ns2 is a discrete event simulator on networking systems, with development capability to add new network protocol models. To study algorithm enhancement or brand new protocol based on ns2, it's inevitable to implement the new algorithm or protocol. Here I discuss the work flow to add a flood routing protocol against ns2.33 specifically.

0. General Work Flow

The work flow is summarized as follows:
Implement the protocol in cpp source code
Modify ns2's cpp headers and tcl files to support and recognize the new protocol
Rebuild the whole ns2 package


1. Implement the New Protocol

1.1 The Flood Routing Protocol
The protocol is essentially a flood routing protocol whose working process is summarized as follows:

To prevent permanent route loop, sequencing is employed, dropping packets from a source node with past sequence number.
On receiving a packet, build a route entry for it in a fashion of {source_node, sequence_number}

The representation and operation of the route table is implemented in 2 C++ classes: MFlood_RTEntry and MFlood_RTable, in file mflood-seqtable.{cc, h}. While the process of the protocol itself is implemented in C++ class MFlood, in file mflood.{cc, h}.

Routine work for our packet type is done in mflood-packet.h.


1.2 Routine for otcl Hook

Though our protocol has been implemented in preceding steps, we have to make it play with the Split Object mechanism of ns2. For that we have to create a TCL class.

static class MFloodclass: public TclClass {
public :
MFloodclass() : TclClass ("Agent/MFlood") {}
TclObject * create(int argc, const char* const* argv) {
std::cout<<"*********running**************"< assert(argc==5);
return (new MFlood((nsaddr_t) atoi(argv[4])));
}
}class_rtProtocolMFlood;

For all agents in ns2, the TCL classes look similar to each other. In the code above, MFlood, the constructor of our routing agent, is involved to play together within the SplitObject hierarchy.

For a further discription of the TCL class, refer to Section 3.5 "Class TclClass" in The ns Manual.


2. Modify ns2's Headers and tcl Library to Recognize our New Agent

2.1 common/packet.h

Add packet type const and an element in class p_info's name_ array.

// insert new packet types here
static const packet_t PT_MFLOOD = 61;
static packet_t PT_NTYPE = 62; // This MUST be the LAST one


class p_info {
...

static void initName()
{
...
//mflood
name_[PT_MFLOOD] = "MFlood";

name_[PT_NTYPE]= "undefined";
}
};


2.2 tcl/lib/ns-packet.tcl

Add code to support mflood's packet header.

foreach prot {

...

# Routing Protocols:
#mflood
MFlood
NV # NixVector classifier for stateless routing
rtProtoDV # distance vector routing protocol
rtProtoLS # link state routing protocol
...

} {
add-packet-header $prot
}


2.3 tcl/lib/ns-lib.tcl

The instance procedure create-wireless-node of otcl class Simulator, is invoked when creating a wireless node. Here we have to add code to support our agent.

switch -exact $routingAgent_ {
MFlood {
set ragent [$self create-mflood-agent $node]
}
DSDV {
set ragent [$self create-dsdv-agent $node]
}

Do not forget to implement procedure create-mflood-agent, which is invoked in above code, somewhere in this otcl file.


Simulator instproc create-mflood-agent { node } {
set ragent [new Agent/MFlood [$node id]]
$node set ragent_ $ragent
return $ragent
}



2.4 Makefile

Find OBJ_CC, modify the piece of code as follows (at approximately Line 326):

The instance procedure create-wireless-node of otcl class Simulator, is invoked when creating a wireless node. Here we have to add code to support our agent.

wpan/p802_15_4trace.o wpan/p802_15_4transac.o \
apps/pbc.o \
src/mflood/mflood.o src/mflood/mflood-seqtable.o \
$(OBJ_STL)


3. Checklist of Related Files

Created source code and headers include:

mflood-packet.h
mflood-seqtable.h
mflood-seqtable.cc
mflood.h
mflood.cc


Modified ns2's exsiting files are:

common/packet.h
tcl/lib/ns-lib.tcl
tcl/lib/ns-packet.tcl
Makefile

For the modified files I've created a patch file that is available for download. To apply the patch, run

cd ns2
patch -p0 -b < mflood.patch


4. Rebuild the Whole ns2 Package

At the root path of ns2, run the following commands:

make
sudo make install

If you don't use 'sudo' in your Linux OS, run it with super user priviledge instead. For ns2-allinone package, just run the installation shell script again.


5. Run in a Typical Wireless Scenario

In this scenario, which consists of 3 wireless nodes, node0 cannot reach node2 directly. Instead node1 has to forward packets from node0 to node2. Below is a snippit of the trace. (otcl script download )

s 0.500000000 _0_ AGT --- 0 cbr 500 [0 0 0 0] ------- [0:0 2:0 32 0] [0] 0 0
r 0.500000000 _0_ RTR --- 0 cbr 500 [0 0 0 0] ------- [0:0 2:0 32 0] [0] 0 0
s 0.500000000 _0_ RTR --- 0 cbr 520 [0 0 0 0] ------- [0:0 2:0 30 0] [0] 0 0
r 0.504764500 _1_ RTR --- 0 cbr 520 [0 ffffffff 0 800] ------- [0:0 2:0 30 0] [0] 1 0
f 0.506526953 _1_ RTR --- 0 cbr 520 [0 ffffffff 0 800] ------- [0:0 2:0 29 0] [0] 1 0
r 0.511571453 _0_ RTR --- 0 cbr 520 [0 ffffffff 1 800] ------- [0:0 2:0 29 0] [0] 2 0
D 0.511571453 _0_ RTR LOOP 0 cbr 520 [0 ffffffff 1 800] ------- [0:0 2:0 29 0] [0] 2 0
r 0.511571787 _2_ AGT --- 0 cbr 520 [0 ffffffff 1 800] ------- [0:0 2:0 29 0] [0] 2 0

From the trace above, we can see that node0 sends a packet out.
node0 receives a copy of the packet itself before the IP header is added (note the packet size).
node1 receives the packet and forwards it.
As a result, node0 receives it again and drops it immediately.
Finally node2, the real destination, receives it.

And we can find out, that the end to end delay from its origination to destination for this packet, is 0.511571787 - 0.5 = 0.011571787 (s) ~= 11.6 (ms)

Each packet is 500*8 bits, so a transmission delay is 500*8/2E6 = 2 (ms). And there's a random forward delay of 10ms (see mflood.h).
These are the 2 main contributors to the total delay.


6. Future Work

Run more detailed and complex scenarios using this protocol/agent. Add some interesting features for this protocol.




Biblography

[Web] Ros, F.J. and Ruiz, P.M. "Implementing a New Manet Unicast Routing Protocol in NS2 ".http://masimum.dif.um.es/nsrt-howto/html/nsrt-howto.html
[Web] Ke, C.H. "如何使得MFLOOD可以在ns-2.27的環境下運作". http://140.116.72.80/%7Esmallko/ns2/mflood.htm
[Book] 徐雷鸣. 等. "ns与网络模拟" 人民邮电出版社, 2003

如何往NS2中添加新的MAC协议

http://www.baisi.net/thread-4031-1-1.html

原创-----如何往NS2中添加新的MAC协议

网上有关于往NS2中添加新的路由协议的文章,却没有关于往NS2中添加新的MAC协议的文章。下面我给大家讲一下如何往NS2中添加新的MAC协议。
往NS2.29中添加了一个新的MAC协议,暂时命名为LMAC.其实它的代码内容和SMAC一样,我只是想验证一下如何在NS2.29中添加新的协议。
1.在~/ns-allinone-2.29/ns-2.29/mac目录下copy原来的smac.cc和smac.h
cp smac.cc lmac.cc
cp smac.h lmac.h

2.打开lmac.cc和lmac.h,把所有的SMAC替换成LMAC,把所有的smac替换成lmac,把所有的Smac替换成Lmac.

3.修改packet.h
打开packet.h,找到匹配字符串SMAC,然后照着样子修改就可以了。
packet.h在~/ns-allinone-2.29/ns-2.29/common目录下
添加定义访问协议报头的指针
#define HDR_SMAC(p) ((hdr_smac *)hdr_mac::access(p))
#define HDR_LMAC(p) ((hdr_lmac *)hdr_mac::access(p)) // add lmac here
增加LMAC包类型(协议标志),所有的包类型都是PT_开头,如PT_TCP,PT_UDP等,在枚举类型enum packet_t{}中找到 PT_SMAC,
添加LMAC
// SMAC packet
PT_SMAC,
// LMAC packet
PT_LMAC,
注意新添加的协议要在PT_NTYPE之前。
然后在类class p_info{}的构造函数中找到
name_[PT_SMAC]="smac";
添加 name_[PT_LMAC]="lmac";这样就可以通过协议标识寻找协议对应的字符串
同样注意要在 name_[PT_NTYPE]= "undefined";之前定义

4.修改ns-default.tcl文件,在~/ns-allinone-2.29/ns-2.29/tcl/lib目录下
找到
# Turning on/off sleep-wakeup cycles for SMAC
Mac/SMAC set syncFlag_ 1
# Nodes synchronize their schedules in SMAC
Mac/SMAC set selfConfigFlag_ 1
# Default duty cycle in SMAC
Mac/SMAC set dutyCycle_ 10
这里定义了otcl对象的缺省值,我们在这里添加LMAC的缺省值
#add LMAC here
# Turning on/off sleep-wakeup cycles for LMAC
Mac/LMAC set syncFlag_ 1
# Nodes synchronize their schedules in LMAC
Mac/LMAC set selfConfigFlag_ 1
# Default duty cycle in LMAC
Mac/LMAC set dutyCycle_ 10

继续寻找SMAC,找到
# Turning on/off sleep-wakeup cycles for SMAC
Mac/SMAC set syncFlag_ 0
添加相应的LMAC
# Turning on/off sleep-wakeup cycles for LMAC
Mac/LMAC set syncFlag_ 0

5.修改ns-packet.tcl文件,在~/ns-allinone-2.29/ns-2.29/tcl/lib目录下
在foreach prot{}这个函数中找到Smac,
Smac # Sensor-MAC
添加一行: Lmac # A new Sensor-MAC

6.修改Makefile文件,在~/ns-allinone-2.29/ns-2.29/目录下
找到smac.o
mac/mac-802_3.o mac/mac-tdma.o mac/smac.o \
添加lmac.o到ns的目标文件列表:
mac/mac-802_3.o mac/mac-tdma.o mac/smac.o mac/lmac.o\

7.经过以上几步,一个新的协议就一经添加成功了,但是这个新的LMAC协议产生的trace文件格式不正确,
还要修改cmu-trace.cc和cmu-trace.h文件,在~/ns-allinone-2.29/ns-2.29/trace目录下
修改cmu-trace.h文件,找到这一行:
void format_smac(Packet *p, int offset);
增加一行:
void format_lmac(Packet *p, int offset);
然后修改cmu-trace.cc文件,这个文件是修改的关键!!
在void
CMUTrace::format_mac_common(Packet *p, const char *why, int offset)
这个函数中修改,添加进去LMAC
struct hdr_cmn *ch = HDR_CMN(p);
struct hdr_ip *ih = HDR_IP(p);
struct hdr_mac802_11 *mh;
struct hdr_smac *sh;
struct hdr_lmac *ph; // 新添加一个指向lamc包的指针
char mactype[SMALL_LEN];
strcpy(mactype, Simulator::instance().macType());
if (strcmp (mactype, "Mac/SMAC") == 0)
sh = HDR_SMAC(p);
else if (strcmp (mactype,"Mac/LMAC") == 0) // 判断是不是LMAC包,新添加的语句
ph = HDR_LMAC(p);
else
mh = HDR_MAC802_11(p);
继续往下找SMAC,添加LMAC

if (strcmp (mactype, "Mac/SMAC") == 0) {
format_smac(p, offset);
}
else if (strcmp (mactype, "Mac/LMAC") == 0) { //新添加的语句
format_lmac(p, offset);
}
else {
format_mac(p, offset);
}
return;

在if(newtrace){}的判断语句中找到SMAC

// mac layer extension
offset = strlen(pt_->buffer());
if (strcmp(mactype, "Mac/SMAC") == 0) {
format_smac(p, offset);
}
else if (strcmp(mactype, "Mac/LMAC") == 0) { //新添加的语句
format_lmac(p, offset);
}
else {
format_mac(p, offset);
}
继续找SMAC,找到:

(ch->ptype() == PT_SMAC) ? (
(sh->type == RTS_PKT) ? "RTS" :
(sh->type == CTS_PKT) ? "CTS" :
(sh->type == ACK_PKT) ? "ACK" :
(sh->type == SYNC_PKT) ? "SYNC" :
"UNKN") :
packet_info.name(ch->ptype())),
ch->size());
添加LMAC的判断
(ch->ptype() == PT_SMAC) ? (
(sh->type == RTS_PKT) ? "RTS" :
(sh->type == CTS_PKT) ? "CTS" :
(sh->type == ACK_PKT) ? "ACK" :
(sh->type == SYNC_PKT) ? "SYNC" :
"UNKN") :
(ch->ptype() == PT_LMAC) ? ( //这一块代码是新添加的
(ph->type == RTS_PKT) ? "RTS" :
(ph->type == CTS_PKT) ? "CTS" :
(ph->type == ACK_PKT) ? "ACK" :
(ph->type == SYNC_PKT) ? "SYNC" :
"UNKN") :
packet_info.name(ch->ptype())),
ch->size());
这里要好好看看源代码,看清楚程序的结构,不要添加错了
再继续找,添加LMAC
if (strncmp (mactype, "Mac/SMAC", 8) == 0) {
format_smac(p, offset);
}
else if (strncmp (mactype, "Mac/LMAC", 8) == 0) { //新添加的代码
format_lmac(p, offset);
}
else {
format_mac(p, offset);
}
再往下找,找到这个函数:
void
CMUTrace::format_smac(Packet *p, int offset)
{
struct hdr_smac *sh = HDR_SMAC(p);
sprintf(pt_->buffer() + offset,
" [%.2f %d %d] ",
sh->duration,
sh->dstAddr,
sh->srcAddr);
}
照着样子给LMAC写一个相同功能的函数:
void
CMUTrace::format_lmac(Packet *p, int offset)
{
struct hdr_lmac *ph = HDR_LMAC(p);
sprintf(pt_->buffer() + offset,
" [%.2f %d %d] ",
ph->duration,
ph->dstAddr,
ph->srcAddr);
}

然后找到void CMUTrace::format(Packet* p, const char *why)这个函数
添加
switch(ch->ptype()) {
case PT_MAC:
case PT_SMAC:
case PT_LMAC: //这是新添加的LMAC协议
break;
case PT_ARP:
format_arp(p, offset);
break;
最后在文件的开头找到#include
添加#include
到此为止,协议添加完成

8.回到目录~/ns-allinone-2.29/ns-2.29下,执行命令:
make clean
make depend
make
make结束后运行,发现报错,说smac.h和lmac.h有函数重定义了,这是因为cmu-trace.cc文件同时include了smac.h和lmac.h,
所以当smac.h和lmac.h有相同名字的定义时,就会报错,解决方法是把lmac.h中与smac.h重名的类改成其它名字,当然在lmac.cc中要做相应的修改。

9.如何评价新的协议是否添加成功?
在添加新的协议之前,我一经运行了ns smac.tcl,把smac.tr文件备份为smac.tr.bak。添加了新的协议后,我重新运行ns smac.tcl,得到新的smac.tr文件,然后我执行命令
diff -b smac.tr smac.tr.bak
发现这两个文件内容一模一样,说明原来的协议SMAC运行正常。
然后我修改了smac.tcl,命名为lmac.tcl,调用LMAC协议,然后执行命令ns lmac.tcl,产生trace文件lmac.tr
执行命令
diff -b smac.tr lmac.tr
发现这两个trace文件的内容是一样的,这说明LMAC协议添加成功了,耶~~~~~~~~~~~~~~~~~~~~

10.在添加新的协议中注意的一些问题和相关技巧:
添加一个新的协议,要照着原来协议的方法写。其实最简单的方法是把含有SMAC,smac,Smac字符串的文件都找出来,然后照样子添加LMAC协议就可以了。
~/ns-allinone-2.29/ns-2.29/gen下的文件是make的时候自动生成的,不用修改
在~/ns-allinone-2.29/ns-2.29/tcl/lib下,文件ns-lib.tcl也含有SMAC的内容,主要是在tcl调用smac时大印出警告语句,告诉用户SMAC要40秒后才能同步。这个文件可以修改,也可以不修改,对运行结果(trace文件)没有影响。


-----------------------------
QQ:631305143
MSN:gmchen@hotmail.com
EE
Fudan University && Shanghai Jiao Tong University
avid
Research Fields: MAC Protocol in WSN, Cross Layer Optimization

NS2 new trace format

###### event type (事件類型) ######
$1 ==> event [s: send(傳送); r: receive(接收); d:drop(丟棄); f: forward(轉送)]

###### general flag ######
$2 ==> -t
$3 ==> 時間

###### Next hop info (下一站的資訊) ######
$4 ==> -Hs
$5 ==> id for this node

$6 ==> -Hd
$7 ==> id for next hop towards the destination

###### Node property type tag (節點屬性類型標籤) ######
$8 ==> -Ni
$9 ==> node id (節點ID)

$10 ==> -Nx
$11 ==> node's x coordinate (節點的x座標位置)

$12 ==> -Ny
$13 ==> node's y coordinate (節點的y座標位置)

$14 ==> -Nz
$15 ==> node's z coordinate (節點的z座標位置)

$16 ==> -Ne
$17 ==> node energy level

$18 ==> -Nl
$19 ==> trace level [AGT: Agent trace ; RTR: Router trace; MAC: Mac trace]

$20 ==> -Nw
$21 ==> reason for the event (事件發生原因)

###### packet info at MAC level (封包在Mac層的資訊) ######
$22 ==> -Ma
$23 ==> duration

$24 ==> -Md
$25 ==> dest's ethernet address

$26 ==> -Ms
$27 ==> src's ethernet address

$28 ==> -Mt
$29 ==> ethernet type

###### Packet information at IP level (封包在IP層的資訊) ######
$30 ==> -Is
$31 ==> source address.Source port number (來源位置,a.b其中a為節點ID,b為埠號)

$32 ==> -Id
$33 ==> dest address.dest port number (目的位置,c.d其中c為節點ID,d為埠號)

$34 ==> -It
$35 ==> packet type (封包類型)

$36 ==> -Il
$37 ==> packet size (封包大小)

$38 ==> -If
$39 ==> flow id (資料流ID)

$40 ==> -Ii
$41 ==> unique id (唯一的ID編號)

$42 ==> -Iv
$43 ==> ttl value (Time To Live的值)

###### Packet info at Application level(封包在應用層的資訊) ######
包含的應用程式類型如arp, tcp或者是adhoc路由協定像是DSDR, DSR, AODV等等。
這個欄位都是以P所開頭的,且標籤為隨著應用程式不同而不同。

r -t 29.994272667 -Hs 3 -Hd -2 -Ni 3 -Nx 70.00 -Ny 50.00 -Nz 0.00 -Ne -1.000000 -Nl MAC -Nw --- -Ma 0 -Md 0 -Ms 0 -Mt 0

2009-12-17

仙劍奇俠傳三 (電視劇)

曲目曲名演唱類型
1.生生世世愛吳雨霏片頭曲
2.忘記時間胡歌片尾曲
3.此生不換青鳥飛魚插曲
4.光棍胡歌插曲
5.答應不愛你鄭中基插曲
6.偏愛張芸京插曲
7.我做我的王[9]兄弟聯插曲
8.你是我一首唱不完的歌郭蘅祈插曲
9.降魔劍
配樂
10.雪見 — 仙凡之旅
配樂
11.共伴闖天涯
配樂
12.景天 — 護甲
配樂
13.長卿 — 眾生平等
配樂
14.龍葵 — 千年等待
配樂

2009-12-15

NS2 LL (link-layer) Class

14.6 LL (link-layer) Class

The link-layer object is responsible for simulating the data link protocols. Many protocols can be implemented within this
layer such as packet fragmentation and reassembly, and reliable link protocol.
Another important function of the link layer is setting the MAC destination address in the MAC header of the packet. In the
current implementation this task involves two separate issues: finding the next–hop–node’s IP address (routing) and resolving
this IP address into the correct MAC address (ARP). For simplicity, the default mapping between MAC and IP addresses is
one–to–one, which means that IP addresses are re–used at the MAC layer.

VII. A new protocol for ns

NS2 如何傳送一個封包(How to transmit a packet?)