TUN/TAP设备是Linux内核的虚拟网络设备,可以利用TUN设备实现IP数据包的透明传输,TAP设备实现以太网帧的透明传输。利用此项技术,我们就可以在不更改应用程序的基础上使用一些新的传输协议。
TUN/TAP介绍一
TUN/TAP介绍二
TUN/TAP介绍三
基于特定的应用场景,本次使用TAP设备,实现以太网帧的搬运。这里仅仅用于测试,后面可在此基础上使用QUIC协议传输。
网络拓扑:
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.cli import CLI
from mininet.link import TCLink
from mininet.node import OVSKernelSwitch, UserSwitch
import time
######################################################################################
#bw=50
#loss=0
#delay='500ms'
######################################################################################
#
# bw,loss,delay
#
# ____s3____
# / \
# 1 1
# [r1] [r2]
# 0 0
# / \
# / \
# s1 s2
# / \
# / \
# h1 h2
# 10.0.0.1/24 10.0.0.100/24
######################################################################################
net = Mininet( cleanup=True )
h1 = net.addHost('h1',ip='10.0.0.1/24')
h2 = net.addHost('h2',ip='10.0.0.100/24')
s1 = net.addSwitch('s1', cls=OVSKernelSwitch, failMode='standalone')
s2 = net.addSwitch('s2', cls=OVSKernelSwitch, failMode='standalone')
s3 = net.addSwitch('s3', cls=OVSKernelSwitch, failMode='standalone')
r1 = net.addHost('r1')
r2 = net.addHost('r2')
#h1
net.addLink(h1,s1,intfName1='h1-eth0')
#r1
net.addLink(s1,r1,intfName2='r1-eth0')
net.addLink(r1,s3,intfName1='r1-eth1')
#h2
net.addLink(h2,s2,intfName1='h2-eth0')
#r2
net.addLink(s2,r2,intfName2='r2-eth0')
net.addLink(r2,s3,intfName1='r2-eth1')
net.start()
print "build bridge r1-eth0 r1-eth1 "
r1.cmd("ifconfig r1-eth0 10.0.0.10/24")
r1.cmd("ifconfig r1-eth1 10.0.1.10/24")
'''
r1.cmd("brctl addbr br_r1")
r1.cmd("brctl addif br_r1 r1-eth0")
r1.cmd("brctl addif br_r1 r1-eth1")
r1.cmd("ifconfig br_r1 up")
'''
#r1.cmd("sudo route add -net 10.0.0.0/24 dev r1-eth1")
r1.cmd("sysctl net.ipv4.ip_forward=1")
print "build bridge r2-eth0 r2-eth1 "
r2.cmd("ifconfig r2-eth0 10.0.0.20/24")
r2.cmd("ifconfig r2-eth1 10.0.1.20/24")
'''
r1.cmd("brctl addbr br_r2")
r1.cmd("brctl addif br_r2 r2-eth0")
r1.cmd("brctl addif br_r2 r2-eth1")
r1.cmd("ifconfig br_r2 up")
'''
#h1.cmd("route add default gw 10.0.0.10")
#h2.cmd("route add default gw 10.0.0.20")
#r2.cmd("sudo route add -net 10.0.0.0/24 dev r2-eth0")
r2.cmd("sysctl net.ipv4.ip_forward=1")
#example:
#r2.cmd("ifconfig r2-eth0 10.0.2.1/24")
#r2.cmd("ifconfig r2-eth1 10.1.0.2/24")
#r2.cmd("ip route add to 10.0.1.0/24 via 10.1.0.1")
#r2.cmd("sysctl net.ipv4.ip_forward=1")
CLI(net)
net.stop()
初次运行的时候,可能会报一些错,因为需要搭建网络设备TAP,根据提示安装brctl即可。
服务端程序:
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
#include <iostream>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <linux/if_tun.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#define SEND_BUF_SIZE 512
using namespace std;
//全局变量
int tun_fd;
//创建tap设备
int tun_alloc(int flags)
{
char cmd[100];
sprintf(cmd, "sudo echo \"已获得root权限\"");
system(cmd);
struct ifreq ifr;
int fd, err;
char *clonedev =(char *) "/dev/net/tun";
if ((fd = open(clonedev