mininet-wifi自带的mesh组网代码分析
2021-02-11 05:18
标签:lag ber tmp 除了 isset dep sele des mod mn_wifi\examples\meshAP.py net.addAccessPoint(‘ap1‘,
wlans=2, ssid=‘ssid91,‘, position=‘10,10,0‘) 设置的默认值如下:{‘ssid‘: ‘ssid91,‘, ‘listenPort‘: None,
‘inNamespace‘: False, ‘mode‘: ‘g‘, ‘wlans‘: 2, ‘position‘: ‘10,10,0‘, ‘channel‘:
1} cls= UserAP::__init__ AP::__init__ Node_wifi::__init__ Node::checkSetup UserAP::setup 判断 /dev/net/tun 文件在没在,当前是存在的。 存在,不做任何处理,返回。 cls.isSetup = True // 把当前类的isSetup标志设置为True Node_wifi.name = ‘ap1‘ self.intfs = {} // 把自己的接口设置为空 self.ports = {} // 把自己的端口设置为空 self.wlanports = -1 // wlan interfaces to port numbers self.nameToIntf = {} // 所有接口名称 self.isStationary = True Node::startShell() opts = ‘-cd‘ cmd = [‘mnexec‘, ‘-cd‘, ‘env‘, ‘PS1=\x7f‘, ‘bash‘,
‘--norc‘, ‘--noediting‘, ‘-is‘, ‘mininet:ap1‘] self.master = 10, self.slave = 11 // 通过操作系统的openpty函数获得 master为10,slave为11. Node::_popen() Popen::__init__() Popen::_execute_child() // 当前的这个函数在 addAccessPoint 的时候并没有做什么事情,也没有执行什么命令 args = [‘mnexec‘, ‘-cd‘, ‘env‘, ‘PS1=\x7f‘, ‘bash‘,
‘--norc‘, ‘--noediting‘, ‘-is‘, ‘mininet:ap1‘] executable = ‘mnexec‘ errpipe_read, errpipe_write = Popen::pipe_cloexec() r, w = os.pipe() // os.pipe() 方法用于创建一个管道, 返回一对文件描述符(r, w) 分别为读和写。 //
所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。 //
由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。 r=12,w=13 self._set_cloexec_flag(r) // 设置文件描述符标志,这里设置为1 self._set_cloexec_flag(w) // 设置文件描述符标志,这里设置为1 gc_was_enabled = gc.isenabled()
//gc模块是python垃圾回收机制的接口模块,可以通过该module启停垃圾回收、调整回收触发的阈值、设置调试选项 // 获取当前的垃圾回收模块的使能状态 gc.disable() // 禁止垃圾回收 self.pid = os.fork() // 创建子进程,并返回子进程的pid,self.pid=6108 self._child_created = true gc.enable() // 打开垃圾回收开关 如果 self.pid = 0 执行接下来的很多操作 os.execvp 操作系统使用新的进程执行相关命令 os.close(errpipe_write) // 关闭管道的写文件描述符 os._exit(255) // 用于在线程中退出 data = os.read(errpipe_read) 从上面管道的文件描述符里面读取数据 如果data不为空 os.waitpid // 清除上面创建的子进程。 self.stdin = os.fdopen( self.master, ‘r‘ ) 该方法用于通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 self.stdout = self.stdin self.pid = self.shell.pid // 这个进程id就是上面popen创建的进程id self.pollOut = select.poll() self.pollOut.register( self.stdout ) // 注册一个文件描述符,注册后,可以通过poll()方法来检查是否有对应的I/O事件发生 用os.read读取数据 Node::cmd() args = unset HISTFILE; stty -echo; set +m // unset HISTFILE 清除历史记录,stty -echo,禁止回显,set +m,打开监视模式。 Node::sendCmd() os.write( self.stdin.fileno(), encode( data ) ) //
调用操作系统的把数据写入文件句柄。但是这个写入的命令并不是创建一个交换机的命令啊?? Node::mountPrivateDirs self.dpid = self.defaultDpid(dpid) nums = re.findall(r‘\d+‘, self.name) // 返回string中所有与pattern相匹配的全部字串,返回形式为数组. nums=1 dpid = 1 返回值 = ‘100000000001‘ self.listenPort = None if not self.inNamespace: // 如果没有名字空间,就分配一个控制器侧的接口。 self.controlIntf = Intf(‘lo‘, self, port=0) // 这个应该是分配当前AP的控制器侧接口。分配的接口名称是‘lo‘ Intf::__init__ ip = {str} ‘127.0.0.1‘ link = {NoneType} None mac = {NoneType} None name = {str} ‘lo‘ node = {UserAP} ap1 prefixLen = {int} 8 Node_wifi::addIntf(self, intf, port=None,
moveIntfFn=moveIntf) self.intfs[port=0] = {intf} lo self.ports[intf] = port = 0 self.nameToIntf[intf.name] = intf Intf::config() //
这里根据参数配置接口,这里参数为空,没有做任何配置。 pathCheck(‘ofdatapath‘, ‘ofprotocol‘, moduleName=‘the
OpenFlow reference user switch‘ + ‘(openflow.org)‘) moduledeps.pathCheck util.quietRun cmd = ‘which ofdatapath‘ util.errRun( cmd ) popen = Popen( cmd, stdout=PIPE, stderr=stderr,
shell=shell ) data = ‘/usr/local/bin/ofdatapath‘ 判断上述目录有对应的文件,就表示这个模块安装了。否则执行exit(1)退出程序。 self.opts = ‘
--listen=punix:/tmp/ap1.listen‘ self.dpopts = ‘--no-slicing‘ self.nameToNode[‘ap1‘] = {UserAP} ap1 Mininet_wifi::addParameters 参数中有 ‘position‘,设置 node.params[‘position‘]
输入的‘wlans‘参数=2,range(params[‘wlans‘]) =
[0,1],把wlan1和wlan2,分别添加到node的wlan参数里面。添加后的node.params如下: node.params = {‘wlan‘: [‘ap1-wlan1‘, ‘ap1-wlan2‘],
‘ssid‘: ‘ssid91,‘, ‘mac‘: [], ‘mode‘: ‘g‘, ‘position‘: [10.0, 10.0, 0.0],
‘channel‘: 1} 把node.params 中的 ‘antennaGain‘, ‘antennaHeight‘,
‘txpower‘, ‘channel‘, ‘mode‘, ‘freq‘ 参数,设置为默认值。 if node_mode == ‘master‘: 设置 node.params[‘ssid‘] 为输入的参数。 最后设置完的参数是:node.params = {‘wlan‘: [‘ap1-wlan1‘,
‘ap1-wlan2‘], ‘ssid‘: [‘ssid91‘, ‘‘], ‘antennaHeight‘: [1.0, 1.0], ‘range‘: [0,
0], ‘stationsInRange‘: {}, ‘antennaGain‘: [5.0, 5.0], ‘txpower‘: [14, 14],
‘mac‘: [‘‘], ‘mode‘: [‘g‘, ‘g‘], ‘associatedStations‘: [], ‘position‘: [10.0,
10.0, 0.0], ‘freq‘: [2.412, 2.412], ‘channel‘: [‘1‘, ‘1‘]} self.aps.append(ap) net.addAccessPoint函数执行完成。 net.addController(‘c0‘, ip="192.168.0.193",
port=6653) 设置controller类为 RemoteController::__init__ Controller::__init__ cargs = {str} ‘-v ptcp:%d‘ cdir = {NoneType} None command = {str} ‘controller‘ inNamespace = {bool} False ip = {str} ‘192.168.0.193‘ name = {str} ‘c0‘ port = {int} 6653 protocol = {str} ‘tcp‘ Node::__init__ self.checkSetup() self.intfs = {} self.ports = {} self.nameToIntf = {} Node::startShell() // 见添加AP的过程。和上面是一样的,也是没有执行什么命令。 self.controllers.append( controller_new
) self.nameToNode[ name ] =
controller_new net.configureWifiNodes() if not self.ppm_is_set Node_wifi::setPropagationModel module(nodes, self.n_radios, self.alt_module,
**params) //
nodes=ap+station,n_radios=6,alt_module=none, module::__init__ module::start h = subprocess.check_output 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等于4. os.system(‘pkill -f \‘hostapd\‘‘) // kill掉 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 = [‘wlan11‘, ‘wlan10‘, ‘wlan9‘, ‘wlan8‘, ‘wlan7‘,
‘wlan6‘, ‘wlan5‘, ‘wlan4‘, ‘wlan3‘, ‘wlan2‘, ‘wlan1‘, ‘wlan0‘, ‘ap2-mp2‘,
‘ap2-wlan2‘, ‘ap2-wlan1‘, ‘ap1-mp2‘, ‘ap1-wlan2‘, ‘ap1-wlan1‘] 返回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‘ // 列出
mn00s00~mn00s05、mn01s00~mn01s05 这些子目录。 phys = subprocess.check_output(cmd,
shell=True).split("\n") //
执行cmd命令 返回[‘mn00s00‘, ‘mn00s01‘, ‘mn00s02‘, ‘mn00s03‘,
‘mn00s04‘, ‘mn00s05‘, ‘mn01s00‘, ‘mn01s01‘, ‘mn01s02‘, ‘mn01s03‘, ‘mn01s04‘,
‘mn01s05‘, ‘mn02s00‘, ‘mn02s01‘, ‘mn02s02‘, ‘mn02s03‘, ‘mn02s04‘, ‘mn02s05‘,
‘‘] 对phys进行遍历 phy.startswith(self.prefix) prefix==‘mn00s‘ Python
startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False 分别执行如下命令, cmd = [‘hwsim_mgmt‘, ‘-c‘, ‘-n‘, ‘mn03s00‘] // 这些命令是使用导入的模块创建
mac80211_hwsim 设备。 ... cmd = [‘hwsim_mgmt‘, ‘-c‘, ‘-n‘,
‘mn03s05‘] module::get_phy phy = subprocess.check_output("find
/sys/kernel/debug/ieee80211 -name hwsim | cut -d/ -f 6 | sort" 返回 [‘mn00s00‘ ~ ‘mn00s05‘, ‘mn01s00‘ ~ ‘mn01s05‘,
‘mn02s00‘ ~ ‘mn02s05‘, ‘mn03s00‘ ~ ‘mn03s05‘] self.assign_iface(nodes, physicalWlans, phys,
**params) #
iface assign nodes=2个station+2个ap physicalWlans = [‘wlan11‘, ‘wlan10‘, ‘wlan9‘, ‘wlan8‘,
‘wlan7‘, ‘wlan6‘, ‘wlan5‘, ‘wlan4‘, ‘wlan3‘, ‘wlan2‘, ‘wlan1‘, ‘wlan0‘,
‘ap2-mp2‘, ‘ap2-wlan2‘, ‘ap2-wlan1‘, ‘ap1-mp2‘, ‘ap1-wlan2‘,
‘ap1-wlan1‘] self.get_wlan_iface(physicalWlans) 下发 iw dev 2>&1 | grep Interface | awk ‘{print
$2} 命令查询所有的接口,这里返回的是除了上述的物理接口还包括[‘wlan12‘, ‘wlan13‘, ‘wlan14‘, ‘wlan15‘,
‘wlan16‘, ‘wlan17‘] 返回 [‘wlan12‘, ‘wlan13‘, ‘wlan14‘, ‘wlan15‘, ‘wlan16‘,
‘wlan17‘] 对nodes进行遍历 如果是AP 如果是ap1,就把wlan14修改成ap1-wlan1;把wlan15修改成ap1-wlan2 如果是ap2,就把wlan16修改成ap2-wlan1;把wlan17修改成ap2-wlan2 如果是station: sta1 的 wlan=‘sta1-wlan0‘ rfkill = subprocess.check_output(rfkill list | grep
mn00s00 | awk \‘{print $1}\‘| tr -d ":") rfkill list #对应编号的wifi设备 os.system(‘rfkill unblock %s‘ % rfkill[0]) // #打开对应编号的设备 os.system(‘iw phy %s set netns %s‘ % (phys[0],
node.pid)) netns(net
namespace)可以让一台机器上模拟多个网络设备,是网络虚拟化的重要组成,将不同类型的网络应用隔离 ip link set wlan12 down ip link set wlan12 name ap1-wlan0 // 改名,如果是sta2,就把wlan13修改成sta2-wlan0 configureWirelessLink() 对stations进行遍历 link = TCLinkWirelessStation(node,
intfName1=‘sta1-wlan0‘) WirelessLinkStation.__init__(self, node1, port1=port1,
intfName1=intfName1, cls1=TCWirelessLink, params1[ ‘port‘ ] = node1.newPort() 返回数字 0,应该表示0号端口。 IntfWireless::__init__ Node_wifi::addIntf() 这里只是把接口名称 sta1-wlan0和端口0,添加到node的属性里面去。 这里获取的link就是 {TCLinkWirelessStation}
sta1-wlan0wifi configureMacAddr() Node::setMAC
(sta1-wlan0,‘00:00:00:00:00:11‘) IntfWireless::setMAC self.cmd(‘ip link set down‘) self.cmd(‘ip link set address ‘00:00:00:00:00:11‘ ‘) 设置mac地址 self.cmd(‘ip link set up‘) createVirtualIfaces // 对stations创建虚接口 AccessPoint(self.aps, self.driver,
self.link) aps = 2个ap; driver = {str} ‘nl80211‘; link = {type}
AccessPoint::__init__ AccessPoint::configure for ap in aps: cls.configAP(ap, wlan) // 配置ap的wlan参数 TCLinkWirelessAP::__init__ WirelessLinkAP.__init__ IntfWireless::__init__() 参数是:node = {UserAP} ap1;name =
{str} ‘ap1-wlan1‘;port = {int} 1 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() for ap in aps: 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 wmediumd::__init__ wmediumd::configureWmediumd
下面是对ap和station都操作了的 设置 wmediumd 的位置和发射功率 start_wmediumd(intfrefs, wmediumd.links,
wmediumd.positions,fading_coefficient, noise_threshold,wmediumd.txpowers,
isnodeaps, propagation_model,maclist) w_starter::start net.addLink(sta1,
ap1) cls = self.infraAssociation(node1, node2, port1, port2, cls,
**params) Association.associate(sta, ap,
enable_wmediumd,enable_interference, **params) 关联到AP configureWirelessLink dist = sta.get_distance_to(ap) 查询sta到ap的距离 cls.associate_infra(sta, ap, **params) Association.associate_noEncrypt(sta, ap, wlan,
ap_wlan) //
无加密连接 cmd = iwconfig sta1-wlan0 essid ssid91 ap
02:00:00:00:02:00 iwconfig命令用于系统配置无线网络设备或显示无线网络设备信息。 iwconfig命令类似于ifconfig命令,但是他配置对象是无线网卡,它对网络设备进行无线操作,如设置无线通信频段。 essid 设置ESSID;ap 强迫无线网卡向给定地址的接入点注册 Association.update(sta, ap, wlan) 更新ap和sta的部分参数,主要是更新sta和ap的相互关联关系。 net.addLink(ap1,
intf=‘ap1-wlan2‘, cls=mesh, ssid=‘mesh-ssid‘, channel=5) mesh::__init__ 设置ap的ssid参数为 ‘mesh-ssid‘ mesh.name = ‘ap1-wlan2‘ setMeshIface mesh.name = ‘ap1-mp2‘ IntfWireless::setType iw dev %s interface add %s type %s IntfWireless::setMAC ‘02:00:00:00:03:00‘ 设置接口的mac地址 ap1.cmd(‘ip link set ap1-wlan2 down‘) node.params[‘wlan‘][wlan] = self.name 把ap1的wlan的第二个由‘ap1-wlan0‘修改为‘ap1-mp2‘ IntfWireless::setChannel cmd = iw dev ap1-mp2 set channel 5 设置接口的通道 self.ipLink(‘up‘) configureMesh(self, node, wlan,
**params): node.func[wlan] = ‘mesh‘ self.associate(node, wlan, **params) // Performs Mesh Association self.join(‘mesh‘, ssid, freq, ht_cap,
name) cmd = iw dev ap1-mp2 mesh join mesh-ssid freq 2432 //
把该接口加入到mesh网络里面去。 TCLinkWirelessStation::__init__ WirelessLinkStation.__init__ IntfWireless::__init__ 建了接口和port之间的映射关系。intf = {TCWirelessLink} ap1-mp2;port =
{int} 3 ap1.start([c0]) UserAP::start cmd = ofdatapath -i ap1-wlan1,ap1-wlan2,ap1-mp2
punix:/tmp/ap1 -d 100000000001 --no-slicing 1> /tmp/ap1-ofd.log 2>
/tmp/ap1-ofd.log & //
100000000001是自己的pid cmd = ofprotocol unix:/tmp/ap1 tcp:192.168.0.193:6653
--fail=closed --listen=punix:/tmp/ap1.listen 1> /tmp/ap1-ofp.log
2>/tmp/ap1-ofp.log & 执行上述命令启动ofdatapath、ofprotocol这两个进程,这两个进程就是ofsoftswitch的两个进程。 mininet-wifi自带的mesh组网代码分析 标签:lag ber tmp 除了 isset dep sele des mod 原文地址:https://www.cnblogs.com/matthew-2013/p/13043617.html
文章标题:mininet-wifi自带的mesh组网代码分析
文章链接:http://soscw.com/index.php/essay/53900.html