1. 程式人生 > >OpenWrt之上wifi探針簡單實現

OpenWrt之上wifi探針簡單實現

之前一直在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驅動初始化介面中即可。