mininet-wifi无线自组网代码分析
2021-02-09 23:16
标签:amp 接入点 null for stat sso ext mat prefix mn_wifi\examples\double_xxx_xxxx.py 组网图:因为保密要求,省略。 无线自组网实现原理: 对每个node节点(所有的节点的基类都是Node)启动一个shell进程,记住进程的pid。通过导入的mac80211_hwsim模块,创建若干个(就是每个node的wlans参数的总和)无线网络设备(这里包括了phy和dev,phy表示无线网络设备,dev表示接口,他们是一一对应的关系),把每个网络设备加入到名称为"某个进程id"的网络名字空间里面去。把接口改一下名称(比如ap1-wlan1改成ap1-mp1)。用hostapd这个程序把每个无线接口配置好,启动这个无线热点。addlink的时候,如果是station就使用iwconfig命令把当前的station加入到某个热点。如果是ap并且是mesh组网的话,使用类似于“iw dev ap1-mp2 mesh join mesh-ssid
freq 2432”这样的命令把这个热点加入到mesh网络里面去。然后在controller.start和ap.start的时候,在对应的shell里面把相关的进程拉起来。这个就完成了整个网络的搭建过程。 前提,大部分和mininet-wifi自带的mesh组网的代码的流程相同。下面只讲差异点,mininet-wifi自带mesh组网代码分析见下面的连接: https://www.cnblogs.com/matthew-2013/p/13043617.html net.addParameters(c1,
False, node_mode=‘master‘, **defaults) 疑问:为什么这里的wlans=1?
控制器的输入参数里面没有wlans参数啊,1是从哪里来的呢? node.func.append(‘none‘) node.phyID.append(0) 在node.params[‘wlan‘]里面添加上‘c1-wlan1‘。————这里只是给node分配wlan的名称,并没有实际创建或者分配wlan的接口。 node.params[‘ip‘] =
[‘‘] node.params[‘mac‘] =
[‘‘] 把node.params 中的 ‘antennaGain=5.0‘,
‘antennaHeight=1.0‘,
‘txpower=14‘, ‘channel=1‘,
‘mode=g‘, ‘freq=2.412‘
参数,设置为默认值。 self.add_range_param(node, **params) // 把range参数初始化为[0,0] if node_mode == ‘master‘: node.params[‘associatedStations‘] = [] node.params[‘stationsInRange‘] = {} node.params[‘mac‘] = [] node.params[‘mac‘].append(‘‘) 设置
node.params[‘ssid‘] 为输入的参数。注意:无线自组网的ssid有可能是这样的 [‘‘,‘2‘]。 node.params[‘ssid‘]=[‘new-ssid‘] net.configureWifiNodes() nodes
= 这里包括3个ap和1个controllor module(nodes, self.n_radios, self.alt_module,
**params) //
nodes=ap+station;n_radios=这个表示当前的网络里面总的无线网卡的数量,当前是7;alt_module=none, module::__init__ module::start h =
subprocess.check_output // subprocess模块用来创建新的进程,连接到其stdin、stdout、stderr管道并获取它们的返回码;在子进程执行命令,以字符串形式返回执行结果的输出。如果子进程退出码 不是0,抛出subprocess.CalledProcessError异常,异常的output字段包含错误输出 cmd =
ps -aux | grep -ic hostapd // 统计hostapd进程的数量 process = Popen(stdout=PIPE, *popenargs, **kwargs) // PIPE=-1,
popenargs = {tuple: 1} ps -aux | grep -ic ‘hostapd‘, kwargs = {dict: 1}
{‘shell‘: True} 但是这个好像也没有执行这个命令。 output, unused_err = process.communicate() // 在这里开启一个子进程,执行上述命令的。ps -aux | grep -ic ‘hostapd‘ == 统计hostapd进程的数量。 if h
>= 2: //
这里的h等于2. os.system(‘pkill -f \‘hostapd\‘‘) // kill掉 hostapd 相关进程。这里为什么要关闭hostapd进程呢? physicalWlans =
module::get_physical_wlan() wlans = subprocess.check_output("iw dev 2>&1 |
grep Interface | awk ‘{print $2}‘", shell=True)).split("\n") iw dev 2>&1
————该命令列出了如下接口。 awk ‘{print $2}‘ 表示把上述内如输出到 标准错误 里面去。 wlans =
[‘‘] ;//
这种组网模式下,获取的接口是空的,为什么呢?
返回wlans //
这里返回的也是空的。 self.load_module(n_radios, nodes, alt_module,
**params) //
初始化wifi模块 n_radios=6,nodes=2个station+2个ap output_ = os.system(‘modprobe mac80211_hwsim radios=0
>/dev/null 2>&1‘) // 导入
mac80211_hwsim 模块,这个就是wifi模块。 self.__create_hwsim_mgmt_devices(n_radios, nodes,
**params) cmd =
‘find /sys/kernel/debug/ieee80211 -name hwsim | cut -d/ -f 6 | sort‘ // 列出 phy。 phys = subprocess.check_output(cmd,
shell=True).split("\n") //
执行cmd命令 返回[‘‘] // 返回的phy为空,为什么? 对phys进行遍历 phy.startswith(self.prefix) prefix==‘mn00s‘ Python
startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False for i in range(0, n_radios):
当前的n_radios=7 分别执行如下命令, cmd =
[‘hwsim_mgmt‘, ‘-c‘, ‘-n‘, ‘mn00s00‘] // 这些命令是使用导入的模块创建名称为‘mn00s00‘ 的mac80211_hwsim 设备。这些命令执行之后,在/sys/kernel/debug/ieee80211/目录下可以看到‘mn00s00‘这些目录都被创建了。注意,这里是dev和phy是同时创建好了的,并且是一一对应关系;phy应该是表示无线网络设备,而dev表示无线网络接口。 ... cmd =
[‘hwsim_mgmt‘, ‘-c‘, ‘-n‘, ‘mn00s06‘] module::get_phy phy = subprocess.check_output("find
/sys/kernel/debug/ieee80211 -name hwsim | cut -d/ -f 6 | sort" 返回
[‘mn00s00‘ ~ ‘mn00s06‘],共计7个phy。 self.assign_iface(nodes, physicalWlans, phys,
**params) # 这个函数的作用启用该无线网络设备,并分配网络名字空间。 nodes=3个ap和1个controller physicalWlans = [] //
上面获取的physicalWlans为空。 wlan_list =
self.get_wlan_iface(physicalWlans)
// 查询到
wlan0~wlan6 这7个接口 下发 iw dev 2>&1 | grep Interface | awk ‘{print
$2} 命令查询所有的接口 返回
[wlan0~wlan6
] 共7个接口。 for
node in nodes: //
对nodes进行遍历 for
wlan in range(0, len(node.params[‘wlan‘])): //
对当前节点的wlan参数进行遍历。 node.phyID[wlan] =0 // 把该节点的物理id分别分配成0、1、2… 无论是ap还是controller都做如下操作: rfkill
= subprocess.check_output(rfkill list | grep mn00s00 | awk ‘{print $1}‘| tr -d
":") // rfkill
list #列出所有可用的wifi设备,返回的是rfkill list的前面的哪个序号。 mn00s00前面的索引号是7,所以返回的是 [‘7‘,‘‘] os.system(‘rfkill unblock %s‘ %
rfkill[0]);// rfkill
unblock 启用索引号为7的wifi设备。 os.system(‘iw phy %s set netns %s‘ % (phys[0],
node.pid)) // 把这个无线设备放入不同的网络名字空间。这个命令执行后,phy和dev在root的shell就查询不到了,应该是加入到node的网络名字空间了。应该从对应的node的shell里面查询才能查询的到了。 node.cmd(‘ip link set %s down‘ %
wlan_list[0]) //
关闭wlan0这个无线网络接口。 node.cmd(‘ip link set %s name %s‘ % (wlan_list[0],
node.params[‘wlan‘][wlan])) // 改名,把wlan0改成ap1-wlan1;wlan1改成ap1-wlan2;wlan2改成ap2-wlan1;wlan3改成ap2-wlan2; self.configureWirelessLink() // 这里只对station的无线接口进行配置,所以这个组网不涉及 createVirtualIfaces // 对stations创建虚接口,这个也不涉及 AccessPoint(self.aps, self.driver,
self.link) aps =
3个ap+1个controller;
driver = {str} ‘nl80211‘; link = {type} AccessPoint::__init__ AccessPoint::configure for ap
in aps: // 对node进行遍历,这里包括了ap和controller for
wlan in range(len(ap.params[‘wlan‘])): // 对node的wlan进行遍历 cls.configAP(ap, wlan) // 配置ap的wlan参数 TCLinkWirelessAP::__init__ WirelessLinkAP.__init__ params1[ ‘port‘ ] = node1.newPort() // 这里只是分配一个int类型的端口号。 intf1 =
IntfWireless::__init__() // 创建一个名称叫 ‘ap1-wlan1‘ 的接口(接口这个类只是mininet的一个类),给这个接口分配一个int类型的端口号。 node.addIntf(self, port=port) //
把端口1和接口‘ap1-wlan1‘建立映射关系 cls.setIPMAC(node, wlan) // 使用命令 ip addr show ap1-wlan1 mac地址:02:00:00:00:02:00 checkNetworkManager(cls, mac) // add mac address into
/etc/NetworkManager/NetworkManager.conf restartNetworkManager() nm_is_running =
os.system(‘service network-manager status 2>&1 | grep -ic running
>/dev/null 2>&1‘) //
查询network-manager服务的状态,这里没有做什么。 for ap
in aps: // 对node进行遍历,这里包括了ap和controller for
wlan in range(len(ap.params[‘wlan‘])): // 对node的wlan进行遍历 cls.setConfig(ap, aps, wlan, link) cls.setHostapdConfig(ap, wlan, aplist,
link) cls.APConfigFile(cmd, ap, wlan) ap = {UserAP} ap1; wlan = {int} 0 cmd = {str} ‘echo
\‘interface=ap1-wlan1\ndriver=nl80211\nssid=ssid91\nwds_sta=1\nhw_mode=g\nchannel=1\nctrl_interface=/var/run/hostapd\nctrl_interface_group=0‘ content = ‘echo
\‘interface=ap1-wlan1\ndriver=nl80211\nssid=ssid91\nwds_sta=1\nhw_mode=g\nchannel=1\nctrl_interface=/var/run/hostapd\nctrl_interface_group=0‘ >
mn10379_ap1-wlan1.apconf‘ ap.cmd(content) // 把 上面的语句写入 mn10379_ap1-wlan1.apconf 文件 cmd = hostapd -B mn10379_ap1-wlan1.apconf // 启动 hostapd;
hostapd是一个带加密功能的无线接入点程序,通过这个配置配置这个无线接入点。 ap.cmd(cmd) // 执行上面的命令 self.configureWmediumd() // 当前配置的无线模式是干扰模式,也就是可以人为插入噪音的。 mob.wmediumd_mode = 3 MyWmediumd::__init__ () // 这里的参数有噪音门限等。这个类是自己实现的类。 MyWmediumd::configureWmediumd 下面是对ap和controller都操作了的 设置 wmediumd 的位置和发射功率 start_wmediumd(intfrefs, wmediumd.links,
wmediumd.positions,fading_coefficient, noise_threshold,wmediumd.txpowers,
isnodeaps, propagation_model,maclist) w_starter::start w_starter::initialize cmdline = [‘wmediumd‘, ‘-l‘, ‘4‘, ‘-s‘, ‘-c‘,
‘/tmp/mn_wmd_config_p_sV91.cfg‘, ‘-x‘,
‘/home/zhangmeng/mininet-wifi/mn_wifi/data/signal_table_ieee80211‘] 执行这个命令 w_server.connect() 启动一个socket,并连接到 ‘/var/run/wmediumd.sock‘
上面去。 for node in nodes: for wlan in range(0,
len(node.params[‘wlan‘])): node.params[‘range‘][wlan] = node.getRange(intf=intf)
// 设置node的range参数。 node.setTxPower(node.params[‘txpower‘][wlan],intf=node.params[‘wlan‘][wlan],setParam=setParam) //
根据node的 txpower 参数信息,设置节点的发射功率。 cmd = iw dev ap1-wlan1 set txpower fixed
1400 执行上面的命令,设置发射功率 node.setAntennaGain(node.params[‘antennaGain‘][wlan],intf=node.params[‘wlan‘][wlan],setParam=setParam) // 根据node的
antennaGain 参数信息,设置节点的天线增益 setGainWmediumd w_server.update_gain(w_gain(self.wmIface[wlan],
int(gain_))) ret = w_server.send_gain_update(gain) cls.sock.send(cls.__create_gain_update_request(gain)) mininet-wifi无线自组网代码分析 标签:amp 接入点 null for stat sso ext mat prefix 原文地址:https://www.cnblogs.com/matthew-2013/p/13055488.html
上一篇:css基础
下一篇:wangEditor上传本地视频
文章标题:mininet-wifi无线自组网代码分析
文章链接:http://soscw.com/index.php/essay/53301.html