我們在使用VMWARE的虛擬化軟體時經常會發現它們能都能虛擬出一個網卡,貌似很神奇的技術,其實在Linux下很簡單,有兩種虛擬設 備,TUN時點對點的裝置,tap表示乙太網路裝置的,做為虛擬網卡驅動,Tun/tap驅動程式的資料接收和發送並不直接和真實網卡打交道,而是通 過使用者態來轉交。在linux下,要實現核心態和使用者態資料的互動,有多種方式:可以通用socket建立特殊通訊端,利用通訊端實現資料交 互;通過proc檔案系統建立檔案來進行資料互動;還可以使用裝置檔案的方式,訪問裝置檔案會調用裝置驅動相應的常式,裝置驅動本身就 是核心態和使用者態的一個介面,Tun/tap驅動就是利用裝置檔案實現使用者態和核心態的資料互動。 #include <unistd.h><br />#include <stdio.h><br />#include <curses.h><br />#include <string.h><br />#include <assert.h><br />#include <sys/types.h><br />#include <sys/socket.h><br />#include <netinet/in.h><br />#include <signal.h><br />#include <unistd.h><br />#include <linux/if_tun.h><br />#include <netinet/in.h><br />#include <sys/ioctl.h><br />#include <sys/time.h><br />#include <linux/if.h><br />#include <netinet/in.h><br />#include <arpa/inet.h><br />#include <errno.h><br />#include <fcntl.h><br />int tun_creat(char *dev,int flags)<br />{<br /> struct ifreq ifr;<br /> int fd,err;<br /> assert(dev != NULL);<br /> if((fd = open ("/dev/net/tun",O_RDWR))<0) //you can replace it to tap to create tap device.<br /> return fd;<br /> memset(&ifr,0,sizeof (ifr));<br /> ifr.ifr_flags|=flags;<br /> if(*dev != '/0')<br /> strncpy(ifr.ifr_name,dev,IFNAMSIZ);<br /> if((err = ioctl(fd,TUNSETIFF,(void *)&ifr))<0)<br /> {<br /> close (fd);<br /> return err;<br /> }<br /> strcpy(dev,ifr.ifr_name);<br /> return fd;<br />}</p><p>int main()<br />{<br /> int tun,ret;<br /> char tun_name[IFNAMSIZ];<br /> unsigned char buf[4096];<br /> tun_name[0]='/0';<br /> tun = tun_creat(tun_name,IFF_TAP|IFF_NO_PI);//如果需要配置tun裝置,則把"IFF_TAP"改成“IFF_TUN”<br /> if(tun<0)<br /> {<br /> perror("tun_create");<br /> return 1;<br /> }<br /> printf("TUN name is %s/n",tun_name);<br /> while (1) {<br /> unsigned char ip[4];</p><p> ret = read(tun, buf, sizeof(buf));<br /> if (ret < 0)<br /> break;<br /> memcpy(ip, &buf[12], 4);<br /> memcpy(&buf[12], &buf[16], 4);<br /> memcpy(&buf[16], ip, 4);<br /> buf[20] = 0;<br /> *((unsigned short*)&buf[22]) += 8;<br /> printf("read %d bytes/n", ret);<br /> ret = write(tun, buf, ret);<br /> printf("write %d bytes/n", ret);<br /> }<br /> return 0;<br />}<br />
另開啟一個終端
路由配置:
ifconfig devname 10.0.0.1 up; //10.0.0.1是本虛擬網卡的IP地址,uP是啟用該網卡
route add -net 10.0.0.2 netmask 255.255.255.255 dev devname
ping 10.0.0.2
開始測試