IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> TUN/TAP 学习总结(二) —— Linux TUN demo -> 正文阅读

[系统运维]TUN/TAP 学习总结(二) —— Linux TUN demo

该demo 创建了一个TUN 设备,添加一条静态路由指定TUN设备,demo 程序从TUN读取报文,简单处理ICMP报文,然后送回协议栈,从而使ping命令成功执行。

运行环境

# uname -a
Linux localhost.localdomain 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 

demo 代码

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

#include <arpa/inet.h>
#include <sys/ioctl.h>

#include <linux/if.h>
#include <linux/if_tun.h>

int tun_open(char *dev, int flags)
{
    struct ifreq ifr;
    int fd, err;

    if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
    {
        printf("open /dev/net/tun error %m\n");
        return fd;
    }

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags |= flags;

//    可以指定tun设备名,页可以让系统自动生成
//    if (strlen(dev) > 0)
//        strncpy(ifr.ifr_name, dev, IFNAMSIZ);

    if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) {
        close(fd);
        printf("set tun error %m\n");
        return err;
    }
    strcpy(dev, ifr.ifr_name);


//  将 tun设备 up
    int ctl_fd;
    struct ifreq netifr={0};
    if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
    {
        netifr.ifr_flags |= IFF_UP | IFF_RUNNING;
        strncpy(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
        if(ioctl(ctl_fd, SIOCSIFFLAGS, &netifr))
        {
            printf("Failed to set socket flags:%m\n");
        }
        else 
        {
            printf("%s up\n",ifr.ifr_name);
        }
        close(ctl_fd);
    }
    else
    {
        printf("open socket error %s", ifr.ifr_name);
    }

    return fd;
}


int main(int argc, char *argv[])
{
    int tun, ret;
    char tun_name[IFNAMSIZ];
    unsigned char buf[4096];

     tun_name[0] = '\0';

//  IFF_TUN: 创建一个tun设备
//  IFF_TAP: 创建一个tap设备
//  IFF_NO_PI: 不包含包信息,默认每个数据包当传到用户空间时,都将包含一个附加的包头来保存包信息
     tun = tun_open(tun_name, IFF_TUN | IFF_NO_PI);
    if (tun < 0) {
        perror("tun_create");
        return 1;
    }
    printf("TUN name is %s\n", tun_name);

    char cmd[1024]={0};

//  设置tun 的IP和掩码
    snprintf(cmd,sizeof(cmd),"ifconfig %s 192.168.1.201/24",tun_name);
    printf("%s\n",cmd);
    system(cmd);

//  添加一条静态路由,将10.10.10.0/24 网段报文的出口设置为 tun
    snprintf(cmd,sizeof(cmd),"route add -net 10.10.10.0 netmask 255.255.255.0 %s",tun_name);
    printf("%s\n",cmd);
    system(cmd);


    while (1)
    {
        unsigned char ip[4];

        ret = read(tun, buf, sizeof(buf));
        if (ret < 0)
        {
            printf("read tun error %m\n");
            break;
        }
        // 未做报文解析,认为收到的都是ICMP 包,进行简单回复
        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;
}

创tun时flag 必须选择IFF_TUN和IFF_TAP其中的一个,未设置IFF_NO_PI时所附加的包信息头如下:

struct tun_pi {
    unsigned short flags;
    unsigned short proto;
};

demo 运行前
在这里插入图片描述
demo 运行后 网络设备中增加了一个tun0,route 中增加了两条
在这里插入图片描述
ping 任意10.10.10.0 网段的IP 都可以ping通
在这里插入图片描述
wireshark 抓包可以看到,报文没有以太网的mac地址和类型,直接从IP层开始
在这里插入图片描述

参考文章
http://blog.chinaunix.net/uid-317451-id-92474.html

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-25 12:48:54  更:2021-10-25 12:49:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:21:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码