AP模式中多重基础服务集(Multi-BSS)下帧的接收
来源:互联网 发布:上古卷轴美女捏脸数据 编辑:程序博客网 时间:2024/05/29 02:08
我们知道,AP模式下的无线网卡可以创建多个基础服务集(Base Service Set, BSS),我们可以为每一个BSS赋予一个SSID,也可以为每一个BSS设置不同的加密方式和密码。通过多个创建多个BSS的方式,就可以让同一个无线路由器提供不同的无线上网服务。那么问题来了,当AP接收到一个帧的时候,如何判断这个帧是否属于这个AP呢?我一开始认为,当AP接收到一个帧的时候,驱动程序便会循环检查每一个BSS的BSSID,看看是否有和接收到的帧的BSSID字段一致的BSS——如果有就ACK,否则就drop掉。后来当在我阅读ath9k驱动程序源代码的时候,才发现我的想法太天真了——一个AP会不停的收到许多帧,如果每收到一个帧,就去轮询每个BSS来确定这个帧是否属于这个AP,那效率实在是太低了。原来AR5212或者以上的无线网卡驱动采用了一种叫做“BSSID掩码(BSSID masking)”的方式,来决定是否ACK接收到的帧。
假如我们的无线网卡的MAC地址是0001,并且创建了两个BSS(假设为BSS_1和BSS_2),其BSSID分别为0100和1001,那么BSSID掩码就是这样计算的:
mac = 0001 //无线网卡的MAC为0001
bssid_mask = 1111; //掩码的初始值为1111
bssid_1 = 0100 //BSS_1的BSSID为0100
bssid_2 = 1001 //BSS_2的BSSID为1001
bssid_mask = bssid_mask & ~(mac ^ bssid_1) //BSS_1被创建后的掩码
= 1111 & ~(0001 ^ 0100)
= 1111 & 1010
= 1010
bssid_mask = bssid_mask & ~(mac ^ bssid_2) //然后BSS_2被创建后的掩码
= 1010 & ~(0001 ^ 1001)
= 1010 & 0111
= 0010
即,最后的掩码为0010。意思就是,当接收到一个帧的时候,只需要注意它BSSID字段的倒数第二位。假如这个AP接收到一个帧,它的BSSID字段为0110,因为它的倒数第二位是1,那么这个帧就不属于这个AP,就可以直接drop了。算法如下:
iframe = 0110 //接收到的帧的BSSID字段是0100
allow = (ifame & bssid_mask) == (bssid_mask & mac) ? true : false
= (0110 & 0010) == (0010 & 0001) ? true : false
= 0010 == 0000 ? true : false
= false //这个帧不属于这个AP,直接drop!
再看另一个例子,假如接收到一个帧的BSSID字段为0001,用眼观察,它的倒数第二位是0,那就是属于这个AP的——实际是否如此呢?我们来计算一下:
ifame = 0001 //接收到的帧的BSSID字段是0001
allow = (ifame & bssid_mask) == (bssid_mask & mac) ? true : false
= (0001 & 0010) == (0010 & 0001) ? true : false
= 0000 == 0000 ? true : false
= true //这个帧属于这个AP,ACK它!
的确是这样的——通过BSSID掩码,驱动程序的作者用O(1)的算法秒杀了我之前幼稚又天真的O(n)算法!!
综上所述,每当AP建立一个BSS,便要更新一下BSSID掩码。当只有一个BSS的时候,掩码就是初始掩码1111。(通常MAC地址是48位,那么初始掩码就是ff:ff:ff:ff:ff:ff)掩码的计算方法为
bssid_mask = bssid_mask & ~(mac ^ bssid)
每当接收到一个帧的时候,通过如下的方法来确定这个帧是否属于此AP:
allow = (ifame & bssid_mask == bssid_mask & mac) ? true : false
那么,代码是如何实现的呢?在drivers/net/wireless/ath/ath9k/virtual.c中,有如下代码:
ath9k_vif_iter是这样的:
在drivers/net/wireless/ath/ath9k/main.c中,有个ath9k_add_interface函数,这个函数在创建一个BSS的时候会被调用,代码如下:
由此可见,驱动程序在每次创建一个BSS——驱动程序的层面上看就是一个网络接口(network interface)——便会更新一下BSSID掩码。
0100和1001,根据上面的算法,计算的掩码为0010。假如此时收到一个BSSID字段为1100的帧,根据如下算法计算:
allow = (ifame_bssid & bssid_mask) == (bssid_mask & mac) ? true : false
= (1100 & 0010) == (0010 & 0001) ? true : false
= 0000 == 0000 ? true : false
= true
但是,此AP根本不存在BSSID为1100的BSS!假如此时在同一个信道里面,另一个AP恰好存在一个BSSID为1100的BSS的话,那么这两个AP将同时ACK这个帧,其后果就是哪个ACK帧也不可能被客户端接收到——客户端只好重新发送这个帧——从而形成恶性循环。但是除非是管理员故意这么设置,可能性不大——一般没有人会在同一个信道和覆盖范围里面设置多个AP吧。
- AP模式中多重基础服务集(Multi-BSS)下帧的接收
- AP模式中多重基础服务集(Multi-BSS)下帧的接收
- Multi-Tenancy模式,基础服务大规模扩张的时候,是应该推进了。
- Linux中USB无线网卡实现AP模式(hostapd交叉编译环境下).
- 802.11学习(二)基本服务集BSS
- SoftAp模式下搜索Ap
- wifi模块配置ap模式下出现的问题
- wifi 服务集 - bss/ess/bssid/essid
- MVC3/4项目开发中遇到的ajax提交Json数据到后台Controller处理(接收参数:多重JSON)
- Android AP模式下获取SSID/PASSWORD
- MT7601u-AP模式(hi3518e)
- wifi中的ap、sta、ap+sta模式的含义
- Linux 环境下的 AP (Master) 模式 的USB 无线网卡 (转载)
- linux下比较好的配置无线AP的脚本(非adhoc模式)
- C/C++中.bss段的解释
- 对uboot中BSS段的理解
- C/C++中.bss段的解释
- Snapdragon Flight AP模式下,查看当前连接到热点的设备
- 02-线性结构3. Pop Sequence (25)
- VS2013禁止生成ipch和sdf文件
- 套接字基础知识
- Sirius:密歇根大学开发的免费开源版“Siri”
- 建议java程序员读的几本书
- AP模式中多重基础服务集(Multi-BSS)下帧的接收
- txt转换成pdf的制作方法
- HTTP 错误 500.21 - Internal Server Error处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipel
- Memcached 及 Redis 架构分析和比较
- 对称加密
- VC++6.0工程类型介绍
- Afinal简介
- View 绘制机制
- True love of two old people