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