1. 程式人生 > >linux下建立tuntap網路裝置

linux下建立tuntap網路裝置

目標:在linux下建立bridge虛擬網橋、eth虛擬網絡卡、tuntap介面裝置。通過ping來傳遞報文,通過tuntap使使用者應用程式來收發報文。

環境:測試環境為VMware、Ubuntu14。

1.準備工作。

安裝brctl、tunctl:

輸入brctl和tunctl指令會出現相應指示,輸入相應命令即可。我由於Ubuntu版本較低,在apt-get update時報錯,出現同樣錯誤可參考下面連結解決。

http://webres.wang/404-not-found-error-apt-get-update-ubuntu/?utm_source=tuicool&utm_medium=referral

設定IP:

我採用的方法是由主機來ping通VMware的虛擬網絡卡,需要設定相應的模式。在VMware中設定為HOST-ONLY模式,並在主機中設定vmnet1的IP為192.168.0.2,子網掩碼為255.255.255.0。之後我們會在linux中設定bridge的IP為192.168.0.10作為虛擬機器的IP地址。

2.編寫tuntap程式碼。

此處建立tap裝置,而不是tun裝置。通過read和write讀寫tap,並將得到的報文打印出來。

#include <linux/if_tun.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <error.h>
#include <string.h>   //memset
#include <arpa/inet.h> //ntohs


int tap_create(char *dev, int flags);


int main(int argc, char *argv[])
{
        int tap,ret,i,ret_all=0,time=0,pkts=0;
        char *tap_name = NULL;
        unsigned char buf[1024];


if (argc < 2)
{
printf("Please input tap's name\n");
return -1; 
}


if (argc == 2)
{
tap_name = argv[1];
}
        tap = tap_create(tap_name, IFF_TAP | IFF_NO_PI);


        if (tap < 0) {
                perror("tap_create");
                return 1;
        }
        printf("TAP name is %s\n", tap_name);


        while (1) 
{ 
ret = read(tap, buf, sizeof(buf));
                if (ret < 0)
                {
printf("delay 10 secs\n");
sleep(10);
continue;
}


pkts++;
ret_all+=ret;
printf("read all %d bytes %d pkts\n", ret_all, pkts);
for(i=0;i<ret;i++)
{
if(i%16==0 && i!=0)
printf("\n");
printf("%02x ",buf[i]);
}
printf("\n");
                
                ret = write(tap, buf, ret);
                printf("write %d bytes\n", ret);
for(i=0;i<ret;i++)
{
if(i%16==0 && i!=0)
printf("\n");
printf("%02x ",buf[i]);
}
printf("\n");


        }


        return 0;
}
 
 int tap_create(char *dev, int flags)
 {
     struct ifreq ifr;
     int fd, err;


     if ((fd = open("/dev/net/tun", O_RDWR|O_NONBLOCK)) < 0)
         return fd;


     memset(&ifr, 0, sizeof(ifr));
     ifr.ifr_flags |= flags;
     if (*dev != '\0')
         strncpy(ifr.ifr_name, dev, IFNAMSIZ);
     if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) {
         close(fd);
         return err;
     }
     strcpy(dev, ifr.ifr_name);


     return fd;
 }

3.搭建網路

我們搭建的網路為虛擬網橋br0,連線eth0和tap100。在shell中輸入以下程式碼建立br0和eth0:

brctl addbr br0
brctl addif br0 eth0
ifconfig br0 192.168.0.10 netmask 255.255.255.0 up

然後在另一個shell終端執行我們寫的tap.c檔案,程式碼如下:

gcc tap.c -o tao
sudo ./tap tap100

程式執行,在第一個shell中再寫入程式碼:

sudo ip link set dev tap100 up  //該程式碼使tap裝置UP,我在測試中發現如果不加tap裝置會收不到資料
sudo brctl addif br0 tap100

然後在主機中啟動cmd,通過程式碼:

ping 192.168.0.11 -t

4.測試結果


5.另

在後來測試中需要設定tap裝置的MAC地址,後來採用瞭如下程式碼:

//用例:tap_setMAC("tap100","08:00:11:22:33:44")
signed char tap_setMAC(const unsigned char *interface_name, const unsigned char *str_macaddr)    
{  
    int             ret;    
    int             sock_fd;    
    struct ifreq    ifr;        
    unsigned int    mac2bit[6];  
      
    if(interface_name == NULL || str_macaddr == NULL)  
    {  
        return -1;  
    }  


    //提取mac格式   
    sscanf((char *)str_macaddr, "%02X:%02X:%02X:%02X:%02X:%02X", (unsigned int *)&mac2bit[0], (unsigned int *)&mac2bit[1], (unsigned int *)&mac2bit[2], (unsigned int *)&mac2bit[3], (unsigned int *)&mac2bit[4], (unsigned int *)&mac2bit[5]);  
      
    sock_fd = socket(PF_INET, SOCK_DGRAM, 0);    
    if (sock_fd < 0)    
    {            
        return -2;    
    }    
      
    sprintf(ifr.ifr_ifrn.ifrn_name, "%s", interface_name);    
    ifr.ifr_ifru.ifru_hwaddr.sa_family = 1;    
    ifr.ifr_ifru.ifru_hwaddr.sa_data[0] = mac2bit[0];  
    ifr.ifr_ifru.ifru_hwaddr.sa_data[1] = mac2bit[1];  
    ifr.ifr_ifru.ifru_hwaddr.sa_data[2] = mac2bit[2];  
    ifr.ifr_ifru.ifru_hwaddr.sa_data[3] = mac2bit[3];  
    ifr.ifr_ifru.ifru_hwaddr.sa_data[4] = mac2bit[4];  
    ifr.ifr_ifru.ifru_hwaddr.sa_data[5] = mac2bit[5];  
      
    ret = ioctl(sock_fd, SIOCSIFHWADDR, &ifr);    
    if (ret != 0)    
    {    
        return -4;    
    }    
      
    close( sock_fd ); 
  
      
    return 0;    
}  


相關推薦

linux建立tuntap網路裝置

目標:在linux下建立bridge虛擬網橋、eth虛擬網絡卡、tuntap介面裝置。通過ping來傳遞報文,通過tuntap使使用者應用程式來收發報文。 環境:測試環境為VMware、Ubuntu14。 1.準備工作。 安裝brctl、tunctl: 輸入brctl和tu

Caffe學習筆記1:linux建立自己的資料庫訓練和測試caffe中已有網路

本文是基於薛開宇 《學習筆記3:基於自己的資料訓練和測試“caffeNet”》基礎上,從頭到尾把實驗跑了一遍~對該文中不清楚的地方做了更正和說明。 主要工作如下: 1、下載圖片建立資料庫 2、將圖片轉化為256*256的lmdb格式 3、計算影象均值 4、定義網路修改部分引

Linux 建立 Git 與 GitHub 的連接

需要 name 文件內容 不能 ubunt 一個 成功 objects 開始 Git 是一款開源的分布式版本控制系統,而 GitHub 是依托 Git 的代碼托管平臺。 GitHub 利用 Git 極其強大的克隆和分支功能,使得社區成員能夠自由地參與到開源項目中去。 不過

如何檢視LINUX的一個USB裝置使用的驅動模組

http://unix.stackexchange.com/questions/60078/find-out-which-modules-are-associated-with-a-usb-device Finding the Kernel Driver(s) Th

Linux 上的基礎網路裝置詳解

Linux 抽象網路裝置簡介 和磁碟裝置類似,Linux 使用者想要使用網路功能,不能通過直接操作硬體完成,而需要直接或間接的操作一個 Linux 為我們抽象出來的裝置,既通用的 Linux 網路裝置來完成。一個常見的情況是,系統裡裝有一個硬體網絡卡,Linux 會在系統裡為其生成一個網路裝置例

Linux建立程序的三種方式及特點

在Linux中主要提供了fork、vfork、clone三個程序建立方法。  在linux原始碼中這三個呼叫的執行過程是執行fork(),vfork(),clone()時,通過一個系統呼叫表對映到sys_fork(),sys_vfork(),sys_clone(),再在這三個函式中去呼叫d

Linux建立並執行第一個HelloWorldC與C++程式

1.執行虛擬機器,啟動Ubuntu,進入終端 2.如果未安裝gcc編譯器及vim文字編輯器,首先在終端下輸入如下指令,並輸入密碼進行下載。 sudo apt install gcc sudo apt install vim 3.使用vim文字編輯器,輸入vim指令分別建立我們需要的c及c

linuxtouch的運用以及在linux建立可執行的.sh檔案

linux的touch命令不常用,一般在使用make的時候可能會用到,用來修改檔案時間戳,或者新建一個不存在的檔案。 1.命令格式: touch [選項]... 檔案... 2.命令引數: -a   或--t

Linux配置CentOS7網路設定 獲取ip地址

1、檢視ip地址     ip addr 2、編輯網絡卡配置檔案     cd /etc/sysconfig/network-scripts     vi /ifcfg-ens33   &n

Linux 建立 sftp 使用者並限定目錄

Linux 下建立 sftp 使用者並限定目錄 1、建立 sftpUser 使用者組 [[email protected] ~]# groupadd sftpUser 2、建立 sftpUser 使用者並指定目錄 [[email protected] ~]# useradd -d

linux建立虛擬環境

什麼是virtualenv virtualenv本身是一個獨立的專案,用以隔離不同專案的工作環境。例如,專案A和專案B都是使用Python 2.7.13,但是,專案A需要使用Flask 0.8版本,專案B需要使用Flask 0.9版本。我們只要組合pyenv和virtualenv這兩個工

Linux,檢視USB裝置資訊

Linux下,檢視USB裝置資訊   首先需要將usbfs掛載一下,然後才能檢視。$ mount -t usbfs none /proc/bus/usb $ cat  /proc/bus/usb/devices 或者在檔案(/etc/fstab)中新增如下這句:

Linux利用rtcwake喚醒裝置

轉自https://blog.csdn.net/bulreed/article/details/19907691   以下是在OpenSuse上所做的測試 whereis rtcwake rtcwake: /usr/sbin/rtcwake /usr/share/man/man

Linux建立共享資料夾

1.  是否安裝了samba服務  sudo apt-get install samba  sudo apt-get install smbfs 2.  建立需要共享的目錄/ home/usr/share 在目錄/home/xxxx/shar

linux 建立虛擬環境 python

virtualenv是一個可以在同一計算機中隔離多個python版本的工具。有時,兩個不同的專案可能需要不同版本的python,如 python2.7 / python3.6 ,但是如果都裝到一起,經常會導致問題。virtualenv能夠用於建立獨立的Python虛擬環境,多個Python相互獨立,互不影響。

Linux建立、檢視、提取和修改靜態庫(*.a)

先說明一點,靜態庫檔案是由多個目標檔案打包而成的,在windows下靜態庫檔案的字尾是.lib,而在linux下靜態庫檔案的字尾是.a(a是archive的縮寫,也就是文件檔案)。   廢話少說,下面直接進入主題。   1.建立兩個c檔案:addition.c 和 mul

linux強大的網路管理工具ethtool學習小結

1.ethtool        ethtool 提供了強大的網絡卡及網絡卡驅動管理能力,其具體的實現框架和網路驅動程式及網路硬體關係緊密,容易修改和擴充套件,能夠為 Linux 網路開發人員和管理人員提供對網絡卡硬體,驅動程式和網路協議棧的設定,檢視以及及除錯等功能。

通過stupid-ftpd在linux建立ftp伺服器

使用到的原始碼包為:stupid-ftpd-1.5beta.tar.gz 下載地址: https://sourceforge.net/projects/stupid-ftpd/files/stupid-ftpd/V1_5beta/ 1、解壓原始碼包 tar -vxf stupid-f

mongodb在linux建立使用者步驟

1.首先停掉服務已無許可權的方式啟動(登入無需賬號密碼)直接通過ip和埠連線上的就是最大許可權管理員;①、停掉服務:進入你的mongodb安裝目錄的bin資料夾輸入:./mongod -shutdown -dbpath=usr/local/mongodb/data(注:usr

linux建立使用者和新增使用者許可權

//新增一個名為tommy的使用者 #passwd tommy   //修改密碼 Changing password for user tommy. New UNIX password:     //在這裡輸入新密碼 Retype new UNIX password:  //再次輸入新密碼 passwd: