中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

使用uIP將TUN網(wǎng)卡適配到TAP網(wǎng)卡-tun2tap

想玩虛擬網(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)教它的大帥哥作者吧。本文要說(shuō)的只是它的一個(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)卡,比如說(shuō)Android系統(tǒng),我一直都想知道為什么,但是得到就是一句sorry!作為一個(gè)開(kāi)源的平臺(tái),我逐漸發(fā)現(xiàn)它不是那么的Free,任何平臺(tái)都沒(méi)有Linux那樣任你隨便蹂躪。Android限制API的使用,沒(méi)有root,那么怎么在有限的API接口范圍內(nèi)達(dá)到效果呢?如果說(shuō)Open×××的服務(wù)端使用的一直都是TAP模式的虛擬網(wǎng)卡,難道還要專門為Android單獨(dú)啟動(dòng)一個(gè)TUN模式的服務(wù)嗎?作為一個(gè)偏執(zhí)的人,我絕不這么做!那么我會(huì)想方設(shè)法把Android的TUN網(wǎng)卡適配到TAP模式。
      TUN和TAP的區(qū)別是什么?無(wú)非就是少了一個(gè)以太網(wǎng)鏈路層,內(nèi)核驅(qū)動(dòng)層面不給實(shí)現(xiàn),那么我自己在用戶態(tài)實(shí)現(xiàn)行不?大家都知道,從TUN網(wǎng)卡對(duì)應(yīng)的字符設(shè)備讀取出來(lái)的東西以及寫(xiě)入的東西就是一個(gè)IP數(shù)據(jù)報(bào),那么很簡(jiǎn)單,我只需要實(shí)現(xiàn)以下三點(diǎn)即可:
1.將數(shù)據(jù)從TUN字符設(shè)備讀出來(lái)后封裝一個(gè)以太頭;
2.將數(shù)據(jù)寫(xiě)入TUN字符設(shè)備前去除其以太頭。
3.實(shí)現(xiàn)一個(gè)ARP邏輯,應(yīng)付ARP請(qǐng)求以及為了封裝目標(biāo)MAC地址而主動(dòng)發(fā)送ARP請(qǐng)求。

很簡(jiǎn)單是吧。但是要是真的寫(xiě)起代碼來(lái),還真的要費(fèi)些時(shí)間和精力。
      我早就承認(rèn)我不是一個(gè)真正的程序員,然而我是獵手,我希望用現(xiàn)成的東西幫我完成以上這一切,能重用的東西為何不重用呢,做到這一點(diǎn)需要的是積累,如果你不知道有uIP這么一個(gè)東西,那么可能你現(xiàn)在真的需要自己寫(xiě)代碼了。上周買了一本書(shū),講述iOS以及Mac OS X內(nèi)核編程的,原因是我的蘋(píng)果電腦已經(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語(yǔ)言內(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的代碼便是,在給出具體的修改之前,首先說(shuō)一下除了使用了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)卡模式之后,剩下的就是重寫(xiě)讀寫(xiě)邏輯了,之所以說(shuō)是重寫(xiě)而不是修改是因?yàn)橹貙?xiě)比修改更容易,uIP的好處在于其定義了很多好用的接口而不是它實(shí)現(xiàn)的現(xiàn)成邏輯,使用這些接口或者稍加改動(dòng)的接口來(lái)實(shí)現(xiàn)一個(gè)新的邏輯或許更加容易。

創(chuàng)新互聯(lián)從2013年開(kāi)始,先為永康等服務(wù)建站,永康等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為永康企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wè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的適配,如此一來(lái),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 適配”均無(wú)結(jié)果,換英文搜還是未果,于是按照老外的常用命名邏輯搜索“tun2tap”,“tap2tun”也依然沒(méi)找到什么,反而獲取了幾個(gè)reset...因此我寫(xiě)下此文,還是老想法,希望如果有人想做類似事情的時(shí)候,能幫上點(diǎn)什么,起碼不像我一樣一無(wú)所獲,互聯(lián)網(wǎng)上應(yīng)該應(yīng)有盡有才對(duì)。

文章名稱:使用uIP將TUN網(wǎng)卡適配到TAP網(wǎng)卡-tun2tap
當(dāng)前地址:http://www.rwnh.cn/article48/gopcep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、ChatGPT網(wǎng)站排名、企業(yè)網(wǎng)站制作靜態(tài)網(wǎng)站、網(wǎng)站營(yí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í)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開(kāi)發(fā)
台南市| 漳州市| 海阳市| 麟游县| 大庆市| 公主岭市| 长武县| 博乐市| 法库县| 景谷| 胶州市| 蓝山县| 冕宁县| 深州市| 泽普县| 桃园县| 宁阳县| 崇礼县| 雷州市| 贵阳市| 子洲县| 织金县| 兴安县| 和田县| 磐安县| 讷河市| 绥滨县| 桂阳县| 泰安市| 镇赉县| 周口市| 怀柔区| 湖州市| 阳西县| 天津市| 扎赉特旗| 萍乡市| 垫江县| 贵阳市| 大英县| 菏泽市|