linux下實現虛擬網卡
咱們在使用VMWARE的虛擬化軟件時常常會發現它們能都能虛擬出一個網卡,貌似很神奇的技術,其實在Linux下很簡單,有兩種虛擬設linux
備,TUN時點對點的設備,tap表示以太網設備的,作爲虛擬網卡驅動,Tun/tap驅動程序的數據接收和發送並不直接和真實網卡打交道,而是通socket
過用戶態來轉交。在linux下,要實現核心態和用戶態數據的交互,有多種方式:能夠通用socket建立特殊套接字,利用套接字實現數據交測試
互;經過proc文件系統建立文件來進行數據交互;還可使用設備文件的方式,訪問設備文件會調用設備驅動相應的例程,設備驅動自己就.net
是核心態和用戶態的一個接口,Tun/tap驅動就是利用設備文件實現用戶態和核心態的數據交互。blog
//All right revsered by yoki2009
//mailto:imj040144@tom.com
//Welcome to my blog: http://blog.csdn.net/yoki2009接口
#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;
}ip
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);
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;
}get
另開啓一個終端string
路由配置:
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
開始測試