基于ubuntu tun虚拟网卡设备完成ping的发送与模拟接收

前言

前面我们初步认识了什么是tun设备及基础的工作原理与接收文件的设备文件(节点)、虚拟网卡的启动、添加路由表等操作,为什么进一步理解tun设备与协议栈的通信理解,这次我们将应用层控制tun设备发送ping,通过read读取到,后经过手动组装icmp网络包write到协议栈,模拟远程主机回复给我们的 icmp reply,顺便熟悉下icmp 网络包的协议。

模拟ping发送与接收有什么作用

网络测试和调试:TUN设备可以用于模拟网络环境,以测试和调试网络应用程序和协议。通过模拟Ping发送和接收,您可以检查网络连接是否正常工作,诊断延迟问题,以及测试网络拓扑。

完成事项

在ubuntu 设中使用ping指定网卡命令使得tun设备发送ping包,tun read到后,定义组装icmp reply、调用系统调用write到协议栈,通过tcpdump抓包,验证是否模拟成功

作用

  1. 提高tun 设备的发送、接收与read与write的理解。
  2. 了解ping的协议,ip header、icmp header、icmp date的定义,赋值,校验和等,协议字段的不同,导致的无法被识别为目标request 的reply,为的ping外网做技术储备。

操作列表

  1. 用于读取tun设备节点并处理数据的应用层程序,再模拟发送icmp reply包
  2. 通过ping命令使得tun设备发送icmp包
  3. tcpdump工具抓取流经tun网卡的包

验证与代码流程

  • 用于读取tun设备节点并处理数据的应用层程序,再模拟发送icmp reply包
#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 <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/udp.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/ip_icmp.h>int tun_alloc(int flags)
{struct ifreq ifr;int fd, err;char *clonedev = "/dev/net/tun";if ((fd = open(clonedev, O_RDWR)) < 0) {return fd;}memset(&ifr, 0, sizeof(ifr));ifr.ifr_flags = flags;if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {close(fd);return err;}system("sudo ifconfig tun0 10.0.0.1 up");printf("Open tun/tap device: %s for reading...\n", ifr.ifr_name);return fd;
}int tun_fd, nread;char buffer[1500];char buffer7[1000];
tun_fd = tun_alloc(IFF_TUN | IFF_NO_PI);if (tun_fd < 0) {perror("Allocating interface");exit(1);}
while (1) {//发送数据包到TUN/TAP设备memset(buffer,0,sizeof(buffer));//读取协议栈发送来的信息nread = read(tun_fd, buffer, sizeof(buffer));if (nread < 0) {close(tun_fd);exit(1);}printf("Read %zd bytes from tun/tap device\n", nread);// 以十六进制格式输出IP数据包for (int i = 0; i < nread; i++) {printf("%02X ", buffer[i]);if ((i + 1) % 16 == 0) {printf("\n");}}printf("\n");
uint16_t calculate_checksum(uint16_t *data, int length) {uint32_t sum = 0;while (length > 1) {sum += *data++;length -= 2;}if (length > 0){sum += *((uint8_t *)data);}while (sum >> 16) {sum = (sum & 0xFFFF) + (sum >> 16);}return (uint16_t)(~sum);
}memset(buffer7,0,sizeof(buffer7));// 检查数据包是否为 ICMP Echo 请求struct iphdr *ip_header = (struct iphdr *)buffer7;if( buffer[20]==0x08){struct icmphdr *icmp_header = (struct icmphdr *)(buffer7 + sizeof(struct iphdr));printf("--------是icmp request包-----------\n");printf("--------ID:%02X,%02X,seq num:%02X,%02X-----------\n",buffer[24],buffer[25],buffer[26],buffer[27]);unsigned char id = buffer[24];unsigned char se = buffer[26];unsigned char id1 = buffer[25];unsigned char se1 = buffer[27];unsigned short ID = ((unsigned short)id << 8 )|id1;unsigned short seq = ((unsigned short)se << 8 )|se1;printf("----------ID:%04X,seq:%04X--------------\n",ID,seq);// Manually construct IP headerip_header->version = 4;ip_header->ihl = 5; // Header length in 32-bit words (5 for no options)ip_header->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr) + 56);ip_header->id = htons(12345); // Customize the ID if neededip_header->ttl = 64; // Time to Liveip_header->protocol = IPPROTO_ICMP;ip_header->saddr = inet_addr("192.168.100.137"); // Source IP addressip_header->daddr = inet_addr("10.0.0.1"); // Destination IP addressip_header->check = 0; // Checksum (set to 0 for now, will be calculated later)// Create ICMP header for Echo Replyicmp_header->type = ICMP_ECHOREPLY;icmp_header->code = 0;icmp_header->checksum = 0;icmp_header->un.echo.id = htons(ID); // Customize the ID if neededicmp_header->un.echo.sequence = htons(seq);// Customize the sequence number if neededchar *data = buffer7 + sizeof(struct iphdr) + sizeof(struct icmphdr);memcpy(data,&(buffer[28]),8);memcpy(data+8,&(buffer[36]),48);icmp_header->checksum = calculate_checksum((uint16_t *)icmp_header, sizeof(struct icmphdr) + 56);printf("------------sizeof(struct icmphdr) + sizeof(reply_data):%d--------------------\n",(sizeof(struct icmphdr) + 56));// 发送 ICMP Echo Reply 数据包到 TUN 设备ssize_t bytes_written=write(tun_fd, buffer7, (sizeof(struct icmphdr) + 56+sizeof(struct iphdr)));if (bytes_written < 0) {perror("Failed to write to TUN device");break;}printf("---------ICMP Echo Request sent :%d Bytes-------------\n",bytes_written);}
}close(tun_fd);return 0;
}

编译并执行结果
编译:

$ gcc net_device_user1.c -o net_device_user1
net_device_user1.c: In function ‘main’:
net_device_user1.c:143:28: warning: format ‘%zd’ expects argument of type ‘signed size_t’, but argument 2 has type ‘int’ [-Wformat=]printf("Read %zd bytes from tun/tap device\n", nread);~~^%d
net_device_user1.c:401:82: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]printf("------------sizeof(struct icmphdr) + sizeof(reply_data):%d--------------------\n",(sizeof(struct icmphdr) + 56));~^%ld
net_device_user1.c:409:59: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘ssize_t {aka long int}[-Wformat=]printf("---------ICMP Echo Request sent :%d Bytes-------------\n",bytes_written);

执行结果:

$ sudo ./net_device_user1
SIOCADDRT: File exists
Open tun/tap device: tun0 for reading...
  • 通过ping命令使得tun设备发送icmp包
$ ping -I tun0 192.168.100.137
PING 192.168.100.137 (192.168.100.137) from 10.0.0.1 tun0: 56(84) bytes of data.

ping后,应用程序会有新的日志log

$ sudo ./net_device_user1
SIOCADDRT: File exists
Open tun/tap device: tun0 for reading...
Read 84 bytes from tun/tap device
45 00 00 54 2B FFFFFF8B 40 00 40 01 FFFFFFDF FFFFFFEB 0A 00 00 01 
FFFFFFC0 FFFFFFA8 64 FFFFFF89 08 00 21 FFFFFF9D 53 46 00 01 FFFFFFC2 2D FFFFFFF8 64 
00 00 00 00 FFFFFFFC FFFFFFB5 0D 00 00 00 00 00 10 11 12 13 
14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 
24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 
34 35 36 37 
--------是icmp request包-----------
--------ID:53,46,seq num:00,01-----------
----------ID:5346,seq:0001--------------
------------sizeof(struct icmphdr) + sizeof(reply_data):64--------------------
---------ICMP Echo Request sent :84 Bytes-------------
  • tcpdump工具抓取流经tun网卡的包
sudo tcpdump -i tun0 -w tcpdump.pcap
tcpdump: listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
tcpdump: pcap_loop: The interface went down
16 packets captured
18 packets received by filter
0 packets dropped by kernel

打开tcpdump包:
在这里插入图片描述
正常被协议栈识别

PS

处理icmp网络包的应用层有很多细节问题,在代码中也打印了出来,我们可以利用wireshark的二进制来确定协议与打印出来的二进制之间的关系
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/123189.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7 个适合初学者的项目,可帮助您开始使用 ChatGPT

推荐&#xff1a;使用 NSDT场景编辑器快速搭建3D应用场景 从自动化日常任务到预测复杂模式&#xff0c;人工智能正在重塑行业并重新定义可能性。 当我们站在这场人工智能革命中时&#xff0c;我们必须了解它的潜力并将其整合到我们的日常工作流程中。 然而。。。我知道开始使…

网络技术一:计算机网络概述

计算机网络概述 计算机网络定义 一组自治计算机互联的集合 计算机网络基本功能 资源共享 综合信息服务 分布式处理与负载均衡 计算机网络的类型 局域网 LAN&#xff1a;由用户自行建设&#xff0c;使用私有地址组建的内部网络 城域网 MAN&#xff1a;由运营商或大规模…

sql中的排序函数dense_rank(),RANK()和row_number()

dense_rank()&#xff0c;RANK()和row_number()是SQL中的排序函数。 为方便后面的函数差异比对清晰直观&#xff0c;准备数据表如下&#xff1a; 1.dense_rank() 函数语法&#xff1a;dense_rank() over( order by 列名 【desc/asc】) DENSE_RANK()是连续排序&#xff0c;比如…

docker清理

1. 查看docker 磁盘占用 docker system df 2. 参考&#xff1a; Docker磁盘占用与清理问题_docker system prune_蓝鲸123的博客-CSDN博客

redis未授权访问

文章目录 搭建环境漏洞复现安装Exlopit并使用 前提条件&#xff1a; 1.安装docker docker pull medicean/vulapps:j_joomla_22.安装docker-compose docker run -d -p 8000:80 medicean/vulapps:j_joomla_23.下载vulhub 搭建环境 输入下面命令&#xff0c;来到Redis的路径下&am…

反序列化漏洞复现(typecho)

文章目录 执行phpinfogetshell 执行phpinfo 将下面这段代码复制到一个php文件&#xff0c;命名为typecho_1.0-14.10.10_unserialize_phpinfo.php&#xff0c;代码中定义的类名与typecho中的类相同&#xff0c;是它能识别的类&#xff1a; <?php class Typecho_Feed{const…

【科研论文配图绘制】task7密度图绘制

【科研论文配图绘制】task7密度图绘制 task7 了解密度图的定义&#xff0c;清楚密度图是常用使用常见&#xff0c;掌握密度图绘制。 1.什么是密度图 密度图&#xff08;Density Plot&#xff09;是一种用于可视化数据分布的图表类型。它通过在数据中创建平滑的概率密度曲线…

「网页开发|前端开发|Vue」06 公共组件与嵌套路由:让每一个页面都平等地拥有导航栏

本文主要介绍在多个页面存在相同部分时&#xff0c;如何提取公共组件然后在多个页面中导入组件重复使用来减少重复代码。在这基础上介绍了通过嵌套路由的方式来避免页面较多或公共部分较多的情况下&#xff0c;避免不断手动导入公共组件的麻烦&#xff0c;并且加快页面跳转的速…

Linux监测进程打开文件

分析问题过程中&#xff0c;追踪进程打开的文件可以在许多不同情况下有用&#xff0c;体现在以下几个方面&#xff1a; 故障排除和调试&#xff1a; 当程序出现问题、崩溃或异常行为时&#xff0c;追踪进程打开的文件可以帮助找出问题的根本原因。这有助于快速定位错误&#x…

基于3D扫描和3D打印的产品逆向工程实战【数字仪表】

逆向工程是一种从物理零件创建数字设计的强大方法&#xff0c;并且可以与 3D 扫描和 3D 打印等技术一起成为原型设计工具包中的宝贵工具。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 3D 扫描仪可以非常快速地测量复杂的物体&#xff0c;并且在涉及现实生活参考时可以…

Scrapy简介-快速开始-项目实战-注意事项-踩坑之路

scrapy项目模板地址&#xff1a;https://github.com/w-x-x-w/Spider-Project Scrapy简介 Scrapy是什么&#xff1f; Scrapy是一个健壮的爬虫框架&#xff0c;可以从网站中提取需要的数据。是一个快速、简单、并且可扩展的方法。Scrapy使用了异步网络框架来处理网络通讯&…

下载配置 maven并在 idea 上应用

目录 一 maven 定义 二 Maven特点 三 Maven仓库 四 安装配置maven 步骤一:准备安装包,解压 步骤二:配置maven的环境变量 步骤三:测试maven的环境变量是否配置成功 步骤四:配置maven本地仓库 步骤五:阿里云、腾讯镜像配置 步骤六:全局配置idea的maven路径 步骤七:创建…

为IT服务台构建自定义Zia操作

Zia是manageengine的商业人工智能助手&#xff0c;是ServiceDesk Plus Cloud的虚拟会话支持代理。使用Zia&#xff0c;您可以优化帮助台管理&#xff0c;还可以缩小最终用户与其帮助台之间的差距&#xff0c;Zia通过执行预配置的操作来帮助用户完成他们的服务台任务。 例如&…

基于HBuilder X平台下的 驾校报名考试管理系统 uniapp 微信小程序3n9o5

本课题研究的是基于HBuilder X系统平台下的驾校管理系统&#xff0c;开发这款驾校管理系统主要是为了帮助学员可以不用约束时间与地点进行查看教练信息、考场信息等内容。本文详细讲述了驾校管理系统的界面设计及使用&#xff0c;主要包括界面的实现、控件的使用、界面的布局和…

Helm Deploy Online Rancher Demo

文章目录 简介预备条件在线安装 Rancher Helm Chart选择 SSL 配置安装 cert-managerHelm 安装 Rancher验证 Rancher Server 是否部署成功 简介 Rancher 是一个开源的企业级全栈化容器部署及管理平台。已有超过 1900 万次下载&#xff0c;4000 生产环境的应用。 简单的说&…

PROSOFT PTQ-PDPMV1网络接口模块

通信接口&#xff1a;PROSOFT PTQ-PDPMV1 网络接口模块通常配备了多种通信接口&#xff0c;以便与不同类型的设备和网络进行通信。常见的接口包括以太网、串行端口&#xff08;如RS-232和RS-485&#xff09;、Profibus、DeviceNet 等。 协议支持&#xff1a;该模块通常支持多种…

基于单片机的八路抢答器(数码管版)(独立按键、四位共阳极数码管、指示灯)

随着科学技术的发展和普及&#xff0c;各种各样的竞赛越来越多&#xff0c;其中抢答器的作用也就显而易见。目前很多抢答器基本上采用小规模数字集成电路设计&#xff0c;使用起来不够理想。因此设计一更易于使用和区分度高的抢答器成了非常迫切的任务。现在单片机已进入各个领…

Sui上低Gas费为预言机注入强大动力

在当今世界中&#xff0c;大数据推动了许多真正有用的应用发展&#xff0c;预言机是将这些数据引入区块链的手段。然而&#xff0c;通过预言机进行数据调用需要在区块链上进行交易&#xff0c;并支付相关gas费。Sui保持稳定且低廉gas费的能力&#xff0c;使其成为依赖预言机app…

什么是ETLT?他是新一代数据集成平台?

什么是ETLT&#xff1f; 在现代数据处理和分析的时代&#xff0c;数据集成是一个至关重要的环节。数据集成涉及将来自各种来源的数据合并、清洗、转换&#xff0c;并将其加载到数据仓库或分析平台以供进一步的处理和分析。传统上&#xff0c;数据集成有两种主要方法&#xff0…

13 mysql date/time/datetime/year 的数据存储

前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 datetime/date/time/year 类类型…