使用uIP將TUN網(wǎng)卡適配到TAP網(wǎng)卡-tun2tap-創(chuàng)新互聯(lián)

想玩虛擬網(wǎng)卡一定要玩TUN/TAP(以下簡(jiǎn)稱TAP),想玩TAP一定要知道uIP。uIP是一個(gè)用戶態(tài)實(shí)現(xiàn)的一個(gè)超級(jí)輕量級(jí)的麻雀雖小五臟俱全的TCP/IP協(xié)議棧,相比lwIP要好用好玩得多,具體怎么個(gè)意思,還是請(qǐng)教它的大帥哥作者吧。本文要說的只是它的一個(gè)應(yīng)用,既如何將TUN模式的虛擬網(wǎng)卡適配成TAP模式的虛擬網(wǎng)卡,這個(gè)需求確實(shí)是需要的。
   到底什么時(shí)候需要把TUN模式的虛擬網(wǎng)卡裝bi成一個(gè)TAP模式的虛擬網(wǎng)卡呢?在你想這么做的時(shí)候!我個(gè)人認(rèn)為TAP模式的虛擬網(wǎng)卡特別適合做服務(wù)端,它可以任意橋接物理網(wǎng)段和虛擬網(wǎng)段,但是有些平臺(tái)真的就是不支持TAP模式虛擬網(wǎng)卡,比如說Android系統(tǒng),我一直都想知道為什么,但是得到就是一句sorry!作為一個(gè)開源的平臺(tái),我逐漸發(fā)現(xiàn)它不是那么的Free,任何平臺(tái)都沒有Linux那樣任你隨便蹂躪。Android限制API的使用,沒有root,那么怎么在有限的API接口范圍內(nèi)達(dá)到效果呢?如果說Open×××的服務(wù)端使用的一直都是TAP模式的虛擬網(wǎng)卡,難道還要專門為Android單獨(dú)啟動(dòng)一個(gè)TUN模式的服務(wù)嗎?作為一個(gè)偏執(zhí)的人,我絕不這么做!那么我會(huì)想方設(shè)法把Android的TUN網(wǎng)卡適配到TAP模式。
   TUN和TAP的區(qū)別是什么?無非就是少了一個(gè)以太網(wǎng)鏈路層,內(nèi)核驅(qū)動(dòng)層面不給實(shí)現(xiàn),那么我自己在用戶態(tài)實(shí)現(xiàn)行不?大家都知道,從TUN網(wǎng)卡對(duì)應(yīng)的字符設(shè)備讀取出來的東西以及寫入的東西就是一個(gè)IP數(shù)據(jù)報(bào),那么很簡(jiǎn)單,我只需要實(shí)現(xiàn)以下三點(diǎn)即可:
1.將數(shù)據(jù)從TUN字符設(shè)備讀出來后封裝一個(gè)以太頭;
2.將數(shù)據(jù)寫入TUN字符設(shè)備前去除其以太頭。
3.實(shí)現(xiàn)一個(gè)ARP邏輯,應(yīng)付ARP請(qǐng)求以及為了封裝目標(biāo)MAC地址而主動(dòng)發(fā)送ARP請(qǐng)求。

很簡(jiǎn)單是吧。但是要是真的寫起代碼來,還真的要費(fèi)些時(shí)間和精力。
   我早就承認(rèn)我不是一個(gè)真正的程序員,然而我是獵手,我希望用現(xiàn)成的東西幫我完成以上這一切,能重用的東西為何不重用呢,做到這一點(diǎn)需要的是積累,如果你不知道有uIP這么一個(gè)東西,那么可能你現(xiàn)在真的需要自己寫代碼了。上周買了一本書,講述iOS以及Mac OS X內(nèi)核編程的,原因是我的蘋果電腦已經(jīng)成了垃圾玩具了,心想能像對(duì)待Linux內(nèi)核那樣蹂躪Mac OS內(nèi)核,可是并不是那么回事,知識(shí)和能力需要積累,并不是想當(dāng)然的,雖然操作系統(tǒng)原理都那回事,然而當(dāng)你動(dòng)手的時(shí)候,就會(huì)發(fā)現(xiàn)并非如此!
   還好,我自認(rèn)對(duì)TAP虛擬網(wǎng)卡還算比較熟悉,因此我相信自己可以做到這件TUN適配到TAP的事情,由于自己比較懶,所有使用了uIP,如果不用uIP的話,憑著自己對(duì)以太幀結(jié)構(gòu)以及ARP協(xié)議的理解,也是可以完成代碼的,這個(gè)代碼的關(guān)鍵并不是什么高深的算法或者深刻的理論知識(shí),而是對(duì)協(xié)議格式的理解以及簡(jiǎn)單地掌握C語言內(nèi)存操作的技巧,僅此而已。如果你還對(duì)uIP不熟悉,那就就花10分鐘時(shí)間瀏覽一下,它是超級(jí)簡(jiǎn)單的,它把TAP網(wǎng)卡當(dāng)成網(wǎng)線,在用戶態(tài)實(shí)現(xiàn)了一個(gè)完整的TCP/IP協(xié)議棧。既然uIP在用戶態(tài)實(shí)現(xiàn)了一個(gè)完整的協(xié)議棧,那么它肯定也實(shí)現(xiàn)了ARP邏輯以及以太幀的封裝邏輯,而這正是TUN適配到TAP的時(shí)候所要用到的。
   那么該怎么辦?很簡(jiǎn)單,修改uIP的代碼便是,在給出具體的修改之前,首先說一下除了使用了uIP之外,還使用了simpletun,玩TAP虛擬網(wǎng)卡的如果一頭扎進(jìn)Open×××那就錯(cuò)了,應(yīng)該先玩下simpletun,就一個(gè)C文件,直接gcc編譯即可。我使用simpletun作為服務(wù)端:
simpletun -s -p 12345 -a -i zz0
我之所以使用zz0作為虛擬網(wǎng)卡的名字是因?yàn)檫@樣在ifconfig的時(shí)候它會(huì)在最后,配置它的時(shí)候不用再拖動(dòng)滾動(dòng)條了。很顯然,服務(wù)端使用的是TAP模式,那么客戶端我準(zhǔn)備使用修改后的uIP,由于標(biāo)準(zhǔn)的uIP使用的是TAP,于是我把它修改成TUN模式,只需要將tapdev_init中的IFF_TAP改為IFF_TUN即可。修改了虛擬網(wǎng)卡模式之后,剩下的就是重寫讀寫邏輯了,之所以說是重寫而不是修改是因?yàn)橹貙懕刃薷母菀?,uIP的好處在于其定義了很多好用的接口而不是它實(shí)現(xiàn)的現(xiàn)成邏輯,使用這些接口或者稍加改動(dòng)的接口來實(shí)現(xiàn)一個(gè)新的邏輯或許更加容易。

專注于為中小企業(yè)提供網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)京口免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了上1000+企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

   和標(biāo)準(zhǔn)的uIP不同的是,tun2tap版本的uIP并不從虛擬網(wǎng)卡讀取以太幀,而是從網(wǎng)絡(luò)套接字讀取以太幀,虛擬網(wǎng)卡只是tun2tap版本uIP的“上層”,這一點(diǎn)是和標(biāo)準(zhǔn)的uIP的unix/main.c邏輯完全相反的。以下就是新版的main邏輯代碼:

int main(int argc, char **argv)
{
    .......
    // 設(shè)置本端的IP地址以及MAC,正常邏輯應(yīng)該在獲取虛擬IP地址以后再設(shè)置
    uip_ipaddr(ipaddr, 1,2,3,5);
    uip_sethostaddr(ipaddr);
    uip_ipaddr(ipaddr, 1,2,3,4);
    uip_setdraddr(ipaddr);
    uip_ipaddr(ipaddr, 255,255,255,0);
    uip_setnetmask(ipaddr);
    ... // 設(shè)置MAC地址
        // 初始化和simpletun連接的套接字
    net_init();
       while(1) {
                char raw_tun[UIP_BUFSIZE];
                memset(uip_buf, 0, sizeof(uip_buf));
        // 從套接字讀取數(shù)據(jù),要么為ARP,要么為IP
                uip_len = net_read();
                if(uip_len > 0) {
            // 如果是IP的話,摘掉以太頭送往TUN網(wǎng)卡
                        if(BUF->type == htons(UIP_ETHTYPE_IP)) {
                                char *buf2tun = BUF;
                                buf2tun += sizeof(struct uip_eth_hdr);
                // 送往TUN虛擬網(wǎng)卡
                                tapdev_send(buf2tun, uip_len-sizeof(struct uip_eth_hdr));
            // 如果是ARP的話,回復(fù)ARP請(qǐng)求或者...
                        } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
                // 處理ARP
                                uip_arp_arpin();
                                if(uip_len > 0) {
                    // 回復(fù)ARP
                                        net_send();
                                }
                        }
                } else if(timer_expired(&periodic_timer)) {
                        timer_reset(&periodic_timer);
                        for(i = 0; i < UIP_CONNS; i++) {
                                uip_periodic(i);
                                if(uip_len > 0) {
                                        uip_arp_out();
                                        net_send();
                                }
                        }
                        if(timer_expired(&arp_timer)) {
                                timer_reset(&arp_timer);
                                uip_arp_timer();
                        }
                }
        // 繼續(xù)處理TAP網(wǎng)卡讀出的數(shù)據(jù),封裝上以太幀頭
                memset(uip_buf, 0, sizeof(uip_buf));
                uip_len = tapdev_read(raw_tun,
                                        UIP_BUFSIZE);
                if(uip_len > 0) {
                        memcpy(uip_buf+sizeof(struct uip_eth_hdr),
                                        raw_tun,
                                        uip_len);
            // 要么請(qǐng)求ARP,要么直接發(fā)送數(shù)據(jù)
                        uip_arp_out();
                        net_send();
                }
        }
        return 0;
}

以上代碼基本就完成了TUN到TAP的適配,如此一來,Open×××的服務(wù)端就可以一直使用TAP模式,即便某些平臺(tái)的Open×××必須使用TUN模式,也可以采用以上的方式實(shí)現(xiàn)一個(gè)用戶態(tài)的以太層,在用戶態(tài)封裝/解封裝以太幀。這樣可以大大降低服務(wù)端的復(fù)雜性。
   起初,我希望能直接在網(wǎng)上找到TUN適配到TAP的現(xiàn)成代碼,于是我搜索“TUN TAP 轉(zhuǎn)化”,“TUN TAP 適配”均無結(jié)果,換英文搜還是未果,于是按照老外的常用命名邏輯搜索“tun2tap”,“tap2tun”也依然沒找到什么,反而獲取了幾個(gè)reset...因此我寫下此文,還是老想法,希望如果有人想做類似事情的時(shí)候,能幫上點(diǎn)什么,起碼不像我一樣一無所獲,互聯(lián)網(wǎng)上應(yīng)該應(yīng)有盡有才對(duì)。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

當(dāng)前文章:使用uIP將TUN網(wǎng)卡適配到TAP網(wǎng)卡-tun2tap-創(chuàng)新互聯(lián)
轉(zhuǎn)載來于:http://bm7419.com/article44/dihche.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、網(wǎng)站維護(hù)外貿(mào)建站、手機(jī)網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、自適應(yīng)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作