tap.c代碼
#include<assert.h>#include<fcntl.h>#include<stdio.h>#include<string.h>#include<sys/socket.h>#include<sys/ioctl.h>#include<linux/if.h>#include<linux/if_tun.h>#include<sys/types.h>#include<errno.h>#include<net/route.h>intTap=0;intTap1=0;int interface_up(char*interface_name){int s;if((s = socket(PF_INET,SOCK_STREAM,0))<0){printf("Error create socket :%m/n", errno);return-1;}struct ifreq ifr;strcpy(ifr.ifr_name,interface_name);short flag;flag = IFF_UP;if(ioctl(s, SIOCGIFFLAGS,&ifr)<0){printf("Error up %s :%m/n",interface_name, errno);return-1;}ifr.ifr_ifru.ifru_flags |= flag;if(ioctl(s, SIOCSIFFLAGS,&ifr)<0){printf("Error up %s :%m/n",interface_name, errno);return-1;}return0;}int tun_create(char*dev,int flags){struct ifreq ifr;int fd, err;assert(dev != NULL);if((fd = open("/dev/net/tun", O_RDWR))<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;}int main(int argc,char*argv[]){char tun_name[IFNAMSIZ]="tap0";char tun_name1[IFNAMSIZ]="tap1";Tap=tun_create(tun_name, IFF_TAP | IFF_NO_PI);if(Tap<0){perror("tun_create");return1;}printf("TAP name is %s\n", tun_name);printf("Tap=%d\n",Tap);//interface_up(tun_name);system("ifconfig tap0 10.66.31.185 netmask 255.255.0.0 up");while(1);}
程序要一直運行,否則程序退出后創建的TAP設備會被釋放
在前面講到了TAP口的基本原理。
那么我們直接用TAP口轉發報文和TAP口綁定的虛擬網卡上用socket上發報文有什么區別呢?
我上圖,我們可以看到, Virtual NIC 就是我們的虛擬網卡,那么如果從TAP口進行報文發送的時候,
我們說了,TAP的使用者就相當於遠程機器的網卡,也就是說報文會從虛擬網卡進入到協議棧,然后走內核
的轉發流程進行轉發(如果是本機就再去LocalIn點),否則就通過forward 到postRoute節點再次進入到TAP口,被
TAP接收后到應用層進行再次轉發出去。
但是如果是通過Virtual NIC的socket發送消息就不同了,會先進入到內核,然后進入到轉發面(LocalOut->forward),如果是本機發給本機的,報文就會進入到LocalIn節點,再被socket接收。
如果是非本機的,就會通過postRoute發出去,再進入到TAP口被應用層轉發面走轉發流程。
附件列表
