对于进入的包,包在netif_receive_skb中被截取,对于出去的包,则在dev_queue_xmit,而这两个地方全部都在802.11逻辑的上面,这就涉及到了802.11的设计。
1.作为有线局域网的扩展,要可以和有线局域网无缝桥接,也就是对arp协议透明;
2.由于无线网络物理链路的特殊性,需要设计特殊的帧格式以满足需要。
这两点看上去是矛盾的,其实不然。有两种方案可实现,其一就是将以太帧封装在802.11帧里面,类似隧道那样,其二就是直接通过以太帧构造802.11帧,两种帧只要能保证可以互相生成即可。802.11采用的正是这种方式,数据帧发往无线链路时,由以太帧生成802.11帧,反过来由802.11帧生成以太帧。
这就需要做一个适配层,用来转换两种帧,在linux中,这种适配层表述的很清晰。基于2.6.32的内核,$SRC/driver/net/mac80211目录下面的代码就是适配层的实现。值得注意的是,旧一点的内核版本虽然没有这么清晰的目录结构,代码也是很明白的,总的实现如下图所示:
注意,适配器适配的两种帧并不是平行的,在协议栈上是上下的关系,这是因为我们已经习惯了以太网,因此需要将802.11适配到以太网,而不需要反过来适配,因此对外只需要呈现一个以太网卡接口即可,没有必要再显示一个“无线网卡设备”接口。最终的结果就是802.11和802.3更像是协议栈上的上下层关系,而不是两种平行的协议。
由于802.11的处理逻辑完全在“网卡设备”接口以下,而抓包逻辑则在“网卡设备”接口以上(netif_XX/dev_YY),而Linux内核看到实现了802.11的网卡设备时,所有路径均已经经过了适配层,因此抓包逻辑看到的“无线网卡”上的流量就都成了以太帧了。另外对于实现了基础结构BSS无线AP的无线网卡而言,有时它转发的是两个无线站点之间的流量,为了使“网卡设备”接口这种流量,需要将所有的802.11数据帧在抉择是发往有线网还是发给另一个无线站点之前全部进行适配,适配成以太帧,如下图所示: