如果添加自组网的路由协议(可能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-MAC6. 修改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:诺基亚研究中心招聘实习生