之前一直在rt2860v2上面做探针数据捕获和试验,并没有基于社区的驱动做过,应该也不是特别麻烦,netlink可以沿用以前的,只要找到802.11驱动里面帧解析的地方就可以了,直接通过netlink把数据broadcast到应用层,应用层还是采用之前的接收模块来接收即可,之前的接收模块代码:

https://github.com/lixuande/rt2860v2-detect-user

现在数据获取的代码:

https://github.com/lixuande/wifidetect-openwrt

probe帧数据捕获

要找到驱动里面probe帧捕获的接口,就要简单了解一下linux下无线驱动的实现,这篇文章讲的相对详细一些:

https://blog.csdn.net/zimiao815/article/details/55511338

我们要做的其实只是在接收帧的处理接口捕获probe就足够了,重点关注处理rx数据的handle,在对应的rx.c中有接口:

__ieee80211_rx_handle_packet

对应的函数说明也比较明显:

/*
 * This is the actual Rx frames handler. as it belongs to Rx path it must
 * be called with rcu_read_lock protection.
 */
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
					 struct sk_buff *skb,
					 struct napi_struct *napi)

这个接口就是实际的rx帧处理接口。
在接口中添加我们想要的处理函数:

if (ieee80211_is_probe_req(fc)){ //added by lixuande 20180902
		struct ieee80211_rx_status *sta = IEEE80211_SKB_RXCB(skb);
		
		wifi_detect detect;
			
		detect.subtype = 4;
		detect.frametype = 2;
		detect.rssi0 = (128 - sta->signal);
		detect.rssi1 = sta->signal;
		detect.rssi2 = sta->signal;
		
		send_detectdata_to_user(hdr->addr2, detect);
	}

send_detectdata_to_user是后面通过内核向用户态发送探针数据的接口。这里的subtype和frametype是为了和rt2860v2中的帧格式保持一致,表示管理帧中的probe帧。

帧数据发送

帧数据的发送采用netlink方式。
最初在rt2860v2之上采用过proc节点与用户态交互数据,问题较多,主要是无法多个应用同时获取数据,还是netlink更合适一些。
netlink可以理解为内核态的socket连接,采用的是异步通信方式,支持多播模式,一个内核模块可以将详细广播给多个应用模块,只要每个应用去监听对应的netlink协议枚举就可以。
netlink的代码放在:

https://github.com/lixuande/wifidetect-openwrt

对于netlink初始和退出的接口:

int rt_netlink_init(void);
int rt_netlink_exit(void);

仿照之前rt2860v2,放在mac80211驱动初始化接口中即可。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐