久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

IEEE802.11數(shù)據(jù)幀在Linux上的抓取

 北漂之鄔 2014-08-28
 終于得到了夢(mèng)寐的《802.11無(wú)線網(wǎng)絡(luò)權(quán)威指南》,,雖然是復(fù)印版本,,看起來(lái)也一樣舒服,光看書是不行的,,關(guān)鍵還是自己練習(xí),,這就需要搭建一個(gè)舒服的實(shí)驗(yàn)環(huán)境,抓包是必不可少的了,,因?yàn)橹挥性敿?xì)分析802.11數(shù)據(jù)幀,,才能深入理解協(xié)議的細(xì)節(jié)。軟件上就是這個(gè)理,,手上沒(méi)設(shè)備還是不行,,這可是搭建實(shí)驗(yàn)環(huán)境的第一步,巧婦難為無(wú)米之炊,。設(shè)備問(wèn)題很好解決,,買一個(gè)就行了,,最好買適合DIY的那種,既便宜又不怕折騰壞了,,因此淘寶是一個(gè)好去處,。我搞到了一個(gè)ralink的802.11bgn的無(wú)線網(wǎng)卡,USB2.0的,,除了有點(diǎn)發(fā)熱之外別的都很好,,軟AP信號(hào)足,功率夠,,速度快,。就是驅(qū)動(dòng)不太給力啊。

        硬件有了,,先驅(qū)起來(lái)再說(shuō),,完事之后就要想辦法抓包了,千萬(wàn)別以為抓包很容易,,一個(gè)軟件就搞定,,想抓取802.11的數(shù)據(jù)包,還真得下一番功夫啊,,本文接下來(lái)的部分就談?wù)勎业?02.11抓包經(jīng)歷,。

        Linux內(nèi)核的抓包機(jī)制軟件上全在ptype_all這個(gè)鏈表,而不存在所謂“網(wǎng)卡混雜模式”,,混雜模式主要是硬件上的概念,,有些網(wǎng)卡會(huì)在芯片內(nèi)部完成MAC地址的過(guò)濾,因此必須讓芯片“知道”不要過(guò)濾任何地址這一件事,,因此就有了混雜模式的概念,,對(duì)于無(wú)線網(wǎng)絡(luò),混雜模式在理解上更加復(fù)雜,,因此“不要過(guò)濾任何數(shù)據(jù)幀”和802.11規(guī)定的AP地址過(guò)濾某些行為上是矛盾的,。舉個(gè)例子,一個(gè)沒(méi)有和此AP建立關(guān)聯(lián)的移動(dòng)節(jié)點(diǎn)發(fā)來(lái)的包,,AP按照802.11規(guī)范是要丟掉它的,,然而混雜模式又要求接受它,這就是矛盾,。矛盾的本質(zhì)原因在于無(wú)線鏈路的“無(wú)邊界”特征,,這是電磁波的物理特性導(dǎo)致的。對(duì)于此誰(shuí)也無(wú)能改變,,因此ESS無(wú)線網(wǎng)絡(luò)就不能設(shè)計(jì)成一個(gè)完全的廣播網(wǎng)絡(luò),,否則一個(gè)三維空間的廣播造成的沖突要浪費(fèi)多少資源啊--我們知道有線局域網(wǎng)以太網(wǎng)最初是一個(gè)一維線纜上的廣播而已,現(xiàn)在有了交換機(jī),CSMA/CD基本已經(jīng)不再被使用了,。只能由AP接入點(diǎn)來(lái)負(fù)責(zé)在移動(dòng)節(jié)點(diǎn)之間轉(zhuǎn)發(fā)數(shù)據(jù)幀,,因?yàn)橹挥兴勒l(shuí)跟自己建立了關(guān)聯(lián)。這種區(qū)別造成了無(wú)線網(wǎng)絡(luò)抓包的尷尬,。

        在設(shè)計(jì)上,,操作系統(tǒng)完全避免了這個(gè)尷尬,要么它根本不允許在802.11這個(gè)層次上進(jìn)行抓包,,要么由驅(qū)動(dòng)決定如何實(shí)現(xiàn)抓包,。對(duì)于Linux,高版本內(nèi)核實(shí)現(xiàn)了統(tǒng)一的802.11適配層框架,,驅(qū)動(dòng)的實(shí)現(xiàn)可選使用,,低版本內(nèi)核完全由驅(qū)動(dòng)來(lái)決定能否實(shí)現(xiàn)抓包;對(duì)于Windows,,如果你使用WireShark工具在無(wú)線網(wǎng)卡上進(jìn)行抓包,,會(huì)得到以下錯(cuò)誤:


在Wireshark的網(wǎng)站上,也有類似的說(shuō)法:


這個(gè)may not未免太無(wú)恥了,。然而tcpdump的手冊(cè)上卻說(shuō)可以在monitor mode下抓取802.11幀,然而這卻需要驅(qū)動(dòng)來(lái)支持,。對(duì)Linux而言,,雖然較高版本的內(nèi)核支持了802.11適配層,然而卻不是每個(gè)驅(qū)動(dòng)的實(shí)現(xiàn)都遵循了這個(gè)框架,,比如我手上的ralink的驅(qū)動(dòng)就很扯,,完全按照windows的那一套來(lái)寫的。因此依靠monitor mode來(lái)抓取802.11幀這完全靠不??!接下來(lái)分析Linux的抓包機(jī)制和802.11適配層的關(guān)系以及銜接。

        對(duì)于進(jìn)入的包,,包在netif_receive_skb中被截取,,對(duì)于出去的包,則在dev_queue_xmit,,而這兩個(gè)地方全部都在802.11邏輯的上面,,這就涉及到了802.11的設(shè)計(jì)。
1.作為有線局域網(wǎng)的擴(kuò)展,,要可以和有線局域網(wǎng)無(wú)縫橋接,,也就是對(duì)arp協(xié)議透明;
2.由于無(wú)線網(wǎng)絡(luò)物理鏈路的特殊性,,需要設(shè)計(jì)特殊的幀格式以滿足需要,。

這兩點(diǎn)看上去是矛盾的,其實(shí)不然,。有兩種方案可實(shí)現(xiàn),,其一就是將以太幀封裝在802.11幀里面,,類似隧道那樣,其二就是直接通過(guò)以太幀構(gòu)造802.11幀,,兩種幀只要能保證可以互相生成即可,。802.11采用的正是這種方式,數(shù)據(jù)幀發(fā)往無(wú)線鏈路時(shí),,由以太幀生成802.11幀,,反過(guò)來(lái)由802.11幀生成以太幀。

        這就需要做一個(gè)適配層,,用來(lái)轉(zhuǎn)換兩種幀,,在linux中,這種適配層表述的很清晰,?;?.6.32的內(nèi)核,$SRC/driver/net/mac80211目錄下面的代碼就是適配層的實(shí)現(xiàn),。值得注意的是,,舊一點(diǎn)的內(nèi)核版本雖然沒(méi)有這么清晰的目錄結(jié)構(gòu),代碼也是很明白的,,總的實(shí)現(xiàn)如下圖所示:


注意,,適配器適配的兩種幀并不是平行的,在協(xié)議棧上是上下的關(guān)系,,這是因?yàn)槲覀円呀?jīng)習(xí)慣了以太網(wǎng),,因此需要將802.11適配到以太網(wǎng),而不需要反過(guò)來(lái)適配,,因此對(duì)外只需要呈現(xiàn)一個(gè)以太網(wǎng)卡接口即可,,沒(méi)有必要再顯示一個(gè)“無(wú)線網(wǎng)卡設(shè)備”接口。最終的結(jié)果就是802.11和802.3更像是協(xié)議棧上的上下層關(guān)系,,而不是兩種平行的協(xié)議,。

        由于802.11的處理邏輯完全在“網(wǎng)卡設(shè)備”接口以下,而抓包邏輯則在“網(wǎng)卡設(shè)備”接口以上(netif_XX/dev_YY),,而Linux內(nèi)核看到實(shí)現(xiàn)了802.11的網(wǎng)卡設(shè)備時(shí),,所有路徑均已經(jīng)經(jīng)過(guò)了適配層,因此抓包邏輯看到的“無(wú)線網(wǎng)卡”上的流量就都成了以太幀了,。另外對(duì)于實(shí)現(xiàn)了基礎(chǔ)結(jié)構(gòu)BSS無(wú)線AP的無(wú)線網(wǎng)卡而言,,有時(shí)它轉(zhuǎn)發(fā)的是兩個(gè)無(wú)線站點(diǎn)之間的流量,為了使“網(wǎng)卡設(shè)備”接口這種流量,,需要將所有的802.11數(shù)據(jù)幀在抉擇是發(fā)往有線網(wǎng)還是發(fā)給另一個(gè)無(wú)線站點(diǎn)之前全部進(jìn)行適配,,適配成以太幀,如下圖所示:


這樣,我們知道了為何無(wú)法使用tcpdump抓取802.11幀了,,接下來(lái)就是想辦法抓取到這種幀,。最關(guān)鍵的事情就是找到在哪里802.11幀轉(zhuǎn)化為了以太幀以及相反的轉(zhuǎn)化,而這很容易,,在2.6.32內(nèi)核中,,ieee80211_invoke_rx_handlers函數(shù)里面取到的就是802.11幀,不過(guò)注意,,一定要在__ieee80211_data_to_8023調(diào)用之前,,對(duì)于其它的內(nèi)核版本,也是類似的,。找到了這個(gè)之后,,接下來(lái)需要將以下的代碼添加到你找到的位置:

  1. list_for_each_entry_rcu(ptype, &ptype_all, list) {  
  2.     if (ptype->dev == null_or_orig || ptype->dev == skb->dev ||  
  3.         ptype->dev == orig_dev)  
  4.         ret = deliver_skb(skb, ptype, skb->dev);  
  5.     }  
  6. }  

ptype_all并沒(méi)有導(dǎo)出,那么可以通過(guò)/boot/System.map-2.6.32-5-amd64這個(gè)文件中取得,,這樣就可以使得tcpdump抓取到802.11的數(shù)據(jù)幀,,原汁原味的。同樣的方法也可以用于抓取發(fā)出的802.11數(shù)據(jù)幀,。        到此為止,,不得不插一句,來(lái)看看依靠802.11適配層也就是wireless框架如何來(lái)實(shí)現(xiàn)抓包,,正如tcpdump的手冊(cè)上寫的那樣,,注意這只能在高版本的內(nèi)核上才行得通,我手上的2.6.37則剛好,。在框架內(nèi)部,實(shí)現(xiàn)了ieee80211_rx函數(shù),,該函數(shù)被驅(qū)動(dòng)調(diào)用,,接收來(lái)自驅(qū)動(dòng)的802.11數(shù)據(jù)幀,其中調(diào)用了ieee80211_rx_monitor來(lái)實(shí)現(xiàn)802.11數(shù)據(jù)幀直接上傳到“網(wǎng)卡設(shè)備接口”,,從而越過(guò)了適配層將802.11幀適配到以太幀這一步,,ieee80211_rx_monitor中式這么實(shí)現(xiàn)的:
  1. list_for_each_entry_rcu(sdata, &local->interfaces, list) {  
  2.     if (sdata->vif.type != NL80211_IFTYPE_MONITOR)  
  3.         continue;  
  4.     if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)  
  5.         continue;  
  6.     if (!ieee80211_sdata_running(sdata))  
  7.         continue;  
  8.     if (prev_dev) {  
  9.         skb2 = skb_clone(skb, GFP_ATOMIC);  
  10.         if (skb2) {  
  11.             skb2->dev = prev_dev;  
  12.             netif_receive_skb(skb2);  //直接調(diào)用設(shè)備接口層的函數(shù)實(shí)現(xiàn)之  
  13.         }  
  14.     }  
  15.     prev_dev = sdata->dev;  
  16.     sdata->dev->stats.rx_packets++;  
  17.     sdata->dev->stats.rx_bytes += skb->len;  
  18. }  

這種方式看起來(lái)和我的方法沒(méi)什么兩樣,實(shí)則更妙,,hack一個(gè)鏈表頭總顯得不那么正規(guī),,而導(dǎo)出一個(gè)函數(shù)卻很顯而易見。然而如果驅(qū)動(dòng)不遵照這個(gè)框架來(lái)寫,,框架里面再好的東西也沒(méi)法使用,,事實(shí)上現(xiàn)有的Linux無(wú)線網(wǎng)卡驅(qū)動(dòng)很多都是基于ndiswrapper的,這樣可以直接加載windows上的驅(qū)動(dòng)程序,,如果事情是這樣,,那還好,糟糕的是,有人寫的驅(qū)動(dòng)竟然是個(gè)四不像,。下文分解,。

        事情往往要比你想的復(fù)雜得多,如果你認(rèn)為上面的工作已經(jīng)完成了一大半,,那就大錯(cuò)特錯(cuò)了,,實(shí)際完成的工作才不到1%...!!!我的ralink無(wú)線網(wǎng)卡的驅(qū)動(dòng)在2.6.32上根本就編譯不過(guò),后來(lái)找了一個(gè)Debian4的虛擬機(jī),,編譯過(guò)了,,可是沒(méi)法識(shí)別USB2.0的無(wú)線網(wǎng)卡,于是索性安裝VMWare-tools,,折騰了一上午,,費(fèi)了好大勁,終于裝上了VMWare-tools,,還是無(wú)法識(shí)別,,于是就又開了一個(gè)Redhat虛擬機(jī),內(nèi)核版本2.6.18-92.el5,,終于既可以編譯驅(qū)動(dòng)又可識(shí)別網(wǎng)卡了,,...期間,裝一臺(tái)物理機(jī)器的心都有了,!接下來(lái)終于改修改代碼了,,一打開驅(qū)動(dòng)源碼,MD,,全部是從Windows的NDIS驅(qū)動(dòng)里面移植過(guò)來(lái)的,,Linux內(nèi)核提供的諸多的802.11適配代碼完全沒(méi)有使用,全部都是自己編寫的,,僅僅在最上端使用register_netdevice之類的接口和內(nèi)核銜接,。
        困難一波接著一波,那就一個(gè)一個(gè)解決,。雖然NDIS的代碼不是很熟悉,,但基本的邏輯還是清楚的。在$SRC/sta/rtmp_data.c中找到了STAHandleRxDataFrame函數(shù),,就是它了:
  1. // 1. skip 802.11 HEADER  
  2. {  
  3.     pRxBlk->pData += LENGTH_802_11;  
  4.     pRxBlk->DataSize -= LENGTH_802_11;  
  5. }  

一下子就找準(zhǔn)了,,skip 802.11 HEADER說(shuō)明沒(méi)有skip之前就是802.11幀了,于是將上述的list_for_each_entry_rcu代碼加到這個(gè)代碼上面,,然而且慢,,我們需要自己構(gòu)造skb啊,這可真的麻煩了,,因?yàn)檫@個(gè)驅(qū)動(dòng)完全是自己處理的,,沒(méi)有用到skb...不管怎么說(shuō),,在寫構(gòu)造skb的代嗎之前先用printk將802.11幀打印出來(lái)再說(shuō),于是添加的代嗎變成了下面的樣子:
  1. {  
  2.     int i = 0;  
  3.     char *p = pRxBlk->pData;  
  4.     printk("###################### begin:%d\n", pRxBlk->DataSize);  
  5.     for (i = 0; i < pRxBlk->DataSize; i++) {  
  6.         printk("%02X ", *p & 0x000000ff);  
  7.         p++;  
  8.     }  
  9.     printk("%d \n", ret);  
  10.     printk("###################### end\n");  
  11. }  

然后編譯,,加載rt3070sta.ko,,調(diào)用以下的命令:
ifconfig ra0 up
iwconfig ra0 mode Managed
iwcondig ra0 essid "zhaoya"
ifconfig ra0 190.168.1.123/24
ping 190.168.1.100

使用dmesg查看的結(jié)果如下:


這里就不再解釋802.11幀每一個(gè)字段的具體含義了,涉及到很多細(xì)節(jié),,比如to ap,,from ap等等,不管怎么說(shuō),,成功抓取了802.11的幀,,接下來(lái)就是如何使用正規(guī)的方法來(lái)做了,所謂的正規(guī)方法就是使用AF_PACKET套接字,。

        唉,,真的不明白Taiwan那些寫ralink驅(qū)動(dòng)的那幫家伙為何如此寫驅(qū)動(dòng)呢,Linux內(nèi)核現(xiàn)成的難道不好嗎,?搞的不倫不類的,,光那些函數(shù)變量命名就和GNU的風(fēng)格不符合,也許驅(qū)動(dòng)是首先在Windows上調(diào)通的吧,,這樣為了重用也沒(méi)什么不可以,,然而可苦了我們DIY一族了,當(dāng)然Win粉這里不論...

        可我搞不明白,,為何不直接用ndiswrapper來(lái)安裝Windows的驅(qū)動(dòng)程序呢,,而非要把Windows的驅(qū)動(dòng)移植到Linux,最終不倫不類的...ndiswrapper是什么,?下面簡(jiǎn)述一下,。

        ndiswrapper給那些不想自己編譯無(wú)線網(wǎng)卡的家伙們帶來(lái)了福音,你可以直接使用windows的二進(jìn)制驅(qū)動(dòng)程序(sys文件,,本質(zhì)上是PE格式),。這怎么可能呢,其實(shí)很簡(jiǎn)單,,ndiswrapper就是為Windows驅(qū)動(dòng)程序構(gòu)造了一個(gè)“家園”,一個(gè)基本的運(yùn)行環(huán)境,,滿足Windows驅(qū)動(dòng)的各類調(diào)用,,這個(gè)環(huán)境分為兩類,第一類就是Windows的內(nèi)核基本環(huán)境,,第二類就是NDIS的環(huán)境,,說(shuō)白了就是提供一些函數(shù)并且導(dǎo)出即可,ndiswrapper的示意圖如下:


ndiswrapper給出了兩套接口以及其Linux實(shí)現(xiàn),,這樣Windows的PE驅(qū)動(dòng)文件經(jīng)過(guò)簡(jiǎn)單處理后就可以正常運(yùn)行了,,Windows驅(qū)動(dòng)程序本身看來(lái)外部環(huán)境和Windows的一模一樣,,該調(diào)用的函數(shù)都有,它只管接口,,并不管實(shí)現(xiàn)(針對(duì)接口編程,!)。這個(gè)原理和Linux用戶態(tài)的Wine是一樣的,,Wine也是提供了一個(gè)外部環(huán)境,,比如諸多的dll,Wine的實(shí)現(xiàn)要比ndiswrapper更加復(fù)雜,,因?yàn)閹?kù)太多了,。

        如果使用ndiswrapper,怎么實(shí)現(xiàn)802.11的抓包呢,?雖然說(shuō)Wireshark的網(wǎng)站上的一篇WLAN (IEEE 802.11) capture setup明確提到:
Windows

Capturing WLAN traffic on Windows depends on WinPcap and on the underlying network adapters and drivers. Unfortunately,  most drivers/adapters support neither monitor mode, nor seeing 802.11 headers when capturing, nor capturing non-data  frames.

Promiscuous mode can be set; unfortunately, it's often crippled. In this mode many drivers don't supply packets at all, or don't supply packets sent by the host.

但是修改ndiswrapper還是很容易的,,注意,這個(gè)NDIS并不是WIndows上的NDIS,,這個(gè)NDIS只是一個(gè)接口集合,,其實(shí)現(xiàn)還是Linux,具體怎么做,,不說(shuō)了,。
神說(shuō):再給你一個(gè)月自由自在的時(shí)間...享受吧...

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多