在孤独中享受寂寞,从寂寞中厮杀黎明!分享 http://blog.sciencenet.cn/u/duankesong 假如我不能,我一定要; 假如我一定要,我就一定能!

博文

网络仿真利器NS-2无师自通七天速成系列Ⅶ:协议添加

已有 7827 次阅读 2010-4-7 21:17 |个人分类:网络仿真|系统分类:科研笔记| 网络仿真, 网络模拟, NS-2, NS2

如果添加自组网的路由协议(可能MAC协议也是类似的),需要添加一些接口,基本可以参照AODV。当然,会涉及一些tcl文件,包括ns-lib.tcl ns-default.tcl ns-packet.tcl ns-agent.tcl 
NS-2.30中添加了一个新的MAC协议,暂时命名为LMAC.其实它的代码内容和SMAC一样,我只是想验证一下如何在NS-2.30中添加新的协议。
1.在~/ns-allinone-2.30/ns-2.30/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.30/ns-2.30/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.30/ns-2.30/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.30/ns-2.30/tcl/lib目录下
在foreach prot{}这个函数中找到Smac,
Smac # Sensor-MAC
添加一行: Lmac # A new Sensor-MAC

6.修改Makefile文件,在~/ns-allinone-2.30/ns-2.30/目录下
找到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.30/ns-2.30/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 <smac.h>
添加#include <lmac.h>
到此为止,协议添加完成

8.回到目录~/ns-allinone-2.30/ns-2.30下,执行命令:
   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.30/ns-2.30/gen下的文件是make的时候自动生成的,不用修改
在~/ns-allinone-2.30/ns-2.30/tcl/lib下,文件ns-lib.tcl也含有SMAC的内容,主要是在tcl调用smac时大印出警告语句,告诉用户SMAC要40秒后才能同步。这个文件可以修改,也可以不修改,对运行结果(trace文件)没有影响。


https://blog.sciencenet.cn/blog-428172-309843.html

上一篇:网络仿真利器NS-2无师自通七天速成系列Ⅵ:无线网络模拟与实例
下一篇:附录4:诺基亚研究中心招聘实习生

0

发表评论 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2022-5-17 01:42

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部