golang tun设备创建并监听

golang tun设备创建并监听

linux tun设备文件地址为/dev/net/tun.直接打开即可(关闭文件描述符创建的tun虚拟接口自动注销)

fd,err:=syscall.Open("/dev/net/tun",syscall.O_RDWR,0640)//关闭
syscall.Close(fd)

初始化

  1. 配置ip地址
  2. 启动虚拟网卡
ip addr add xxx.xxx.xxx.xxx/24 dev tuname
ip link set dev tuname up

读取ip包

tun 是位于l3网络层,拿到手就是热乎的ip包,直接读文件描述符就ok

var(buff []byte=make([]byte,1024)lang interr error
)
lang,err=syscall.Read(fd,buff)

开始

查看本机网络接口
请添加图片描述

正常情况下,有2个接口,一个lo 本地,一个enxxxx的物理接口,当然在这里有几个不重要,大概了解下就可以了

创建一个名称为tun01的设备过后(不做初始化)

请添加图片描述

初始化后,这设备接口已经可以正常通了(你甚至可以直接使用这个接口的地址进行tcp/udp通信)

请添加图片描述

这个时候呢,这个go程序这边直接读文件描述符是没数据(最开始有几个大小为48的数据包,那是初始化产生的),也不可能会有数据。经过tun01 接口才能读出数据,但是都这步都没配路由表策略,怎么会有数据走这个接口过.这个时候肯定少不了ip4伴侣ip4 报头(这部分不了解的可以查看我[golang 监听ip包]这边文章,golang ip4头结构体里面都有)

这时候你想接受到数据,你得把你有流量来往的数据的网络设备接口导到你这个网络设备接口。查看路由策略(默认策略在main表中)。这个表看数据流入的看法是先不看default,如果ip4 dst 地址前3个对上了,那么就经过那一行对应的网络设备,一个都没对上,走default via 的那个地址,dev xxxx是用于发送这个ip包的网络设备(也就是说你default那一行乱搞,顶多是没网,你同局域网或者在非default网段的网络还是能上的),这里使用ip route改路由策略不要怕改路由表改错了带来什么影响导致重装系统,直接重启一下,一切都恢复如初

请添加图片描述

更改default 数据走向至tun01

请添加图片描述

请添加图片描述
请添加图片描述

演示代码

package main/*
#include <net/if.h>
#include <linux/if_tun.h>
#include <sys/socket.h>
#include <sys/types.h>
*/
import "C"
import ("encoding/binary""fmt""os""os/exec""os/signal""strconv""syscall""unsafe"
)func Raw2String(src uint32) string {raw := make([]byte, 4)binary.LittleEndian.PutUint32(raw, src)return strconv.FormatUint(uint64(raw[0]), 10) + "." + strconv.FormatUint(uint64(raw[1]), 10) + "." + strconv.FormatUint(uint64(raw[2]), 10) + "." + strconv.FormatUint(uint64(raw[3]), 10)
}// ip包必选,ip6自行根据wireshark进行编写,此处ip4为例
type IPHeader struct {Version_And_Len        uint8 //前4个bit为version(4 ip4,6 ip6),后bit个字节为首部length xxxx xxxxDiffernetialtedService uint8Tot_Len                uint16Id                     uint16Flag_And_Seek          uint16 //前3bit 为flag后面13bit为seekTTL                    uint8Protocol               uint8CheckSum               uint16Source                 uint32Dest                   uint32
}
type Pointer[T any] struct {T    *Tbuff []byte
}func NewPointer[T any]() *Pointer[T] {var t Tvar ans = &Pointer[T]{buff: make([]byte, unsafe.Sizeof(t))} //获取类型占用内存字节数ans.T = (*T)(unsafe.Pointer(&ans.buff[0]))                  //将指针关联过去return ans
}
func (s *Pointer[T]) Bytes() []byte {return s.buff
}
func Open_Tun(tuname string, ipadd string) int {fd, err := syscall.Open("/dev/net/tun", syscall.O_RDWR, 0640)if fd < 0 {fmt.Fprintln(os.Stderr, "open fd failed "+err.Error())return -1}var (ifr C.struct_ifreq)//网络设备接口注册copy(ifr.ifr_ifrn[:len(tuname)], []byte(tuname))flags := NewPointer[uint16]()*flags.T = syscall.IFF_TUN | syscall.IFF_UP | syscall.IFF_MULTICASTcopy(ifr.ifr_ifru[:2], flags.Bytes())ans, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TUNSETIFF, uintptr(unsafe.Pointer(&ifr)))if int32(ans) < 0 {fmt.Fprintln(os.Stderr, err.Error())syscall.Close(fd)return -1}//设备接口初始化cmd := exec.Command("ip", "addr", "add", "192.168.99.99/24", "dev", tuname)cmd.Run()cmd = exec.Command("ip", "link", "set", "dev", tuname, "up")cmd.Run()return fd
}func main() {fd := Open_Tun("tun01", "10.0.0.2")if fd > 0 {ch := make(chan os.Signal, 1)signal.Notify(ch, syscall.SIGINT)go func() {var (ipheader *IPHeader// size     interr  errorbuff []byte = make([]byte, 1024))for {_, err = syscall.Read(fd, buff)if err == nil {if buff[0] == 0x45 { //只看ip4ipheader = (*IPHeader)(unsafe.Pointer(&buff[0]))fmt.Printf("protocol %d src %s dst %s\n", ipheader.Protocol, Raw2String(ipheader.Source), Raw2String(ipheader.Dest))}}}}()<-chsyscall.Close(fd)}
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解flinksql执行流程,calcite与catalog相关概念,扩展解析器实现语法的扩展

深入理解Flink Sql执行流程 1 Flink SQL 解析引擎1.1SQL解析器1.2Calcite处理流程1.2.1 SQL 解析阶段&#xff08;SQL–>SqlNode&#xff09;1.2.2 SqlNode 验证&#xff08;SqlNode–>SqlNode&#xff09;1.2.3 语义分析&#xff08;SqlNode–>RelNode/RexNode&#…

[c++]实例观察返回值优化

1 返回值优化现象 RVO 如下代码&#xff0c;在 MakeObj() 中创建了一个局部对象 obj&#xff0c;并将 obj 返回。 Test() 函数调用了 MakeObj()&#xff0c;并将 MakeObj() 的返回值赋值给了 obj。 按我们的预期&#xff0c;MakeObj() 是值返回&#xff0c;在 main() 调用 Tes…

商业智能信息系统(BI):一文扫盲,全面掌握企业经营状况。

大家好&#xff0c;我是大美B端工场&#xff0c;本期继续分享商业智能信息系统的设计&#xff0c;欢迎大家关注&#xff0c;如有B端写系统界面的设计和前端需求&#xff0c;可以联络我们。 一、BI是什么 商业智能&#xff08;Business Intelligence&#xff0c;简称BI&#xf…

c语言经典测试题5

1.题1 t0; while(printf("*")) { t; if (t<3) break; }关于上述代码描述正确的是&#xff1f; A: 其中循环控制表达式与0等价 B: 其中循环控制表达式与0等价 C: 其中循环控制表达式是不合法的 D: 以上说法都不对 我们来分析一下&#xff1a;printf的返回值…

笔记本Win 10系统查看电池健康状况

博主最近换了个笔记本电池&#xff0c;之前的电池容量明显变小了很多&#xff0c;而且出现了轻微鼓包的情况。所以用gpt问了一下怎么用系统的方法查看电池情况。 在Windows 10系统中&#xff0c;您可以通过以下步骤来查看笔记本电脑电池的健康状况&#xff1a; 打开命令提示符&…

ARM服务器部署Kafka集群

安装前必备的条件是: (1)安装jdk(提供环境); (2)安装zookeeper(注册kafka信息); 需要这方面信息的可以查看我之前写的文档; 一.下载安装包 Kafka官网下载地址 Apache Kafka 根据自己需要下载相应的版本 目前最新的版本是3.6.1。 二.解压安装包 服务器上传下载好的kafk…

VSCODE include错误 找不到 stdio.h

解决办法&#xff1a; Ctrl Shift P 打开命令面板&#xff0c; 键入 “Select Intellisense Configuration”&#xff08;下图是因为我在写文章之前已经用过这个命令&#xff0c;所以这个历史记录出现在了第一行&#xff09; 再选择“Use gcc.exe ”&#xff08;后面的Foun…

智慧公厕与智慧驿站:城市未来公共厕所的革命性升级

在当今社会&#xff0c;智慧公厕已经成为城市建设中一个备受关注的话题。智慧公厕究竟是什么&#xff1f;它代表了未来式的公共厕所&#xff0c;在使用方式、服务方式、管理方式、协作方式上均是变革式的升级。随着科技的进步和城市化的发展&#xff0c;智慧公厕的未来发展趋势…

悄悄话花费的时间(C语言)【二叉树各结点统计求和】

题目描述 给定一个二叉树&#xff0c;每个节点上站着一个人&#xff0c;节点数字表示父节点到该节点传递悄悄话需要花费的时间。 初始时&#xff0c;根节点所在位置的人有一个悄悄话想要传递给其他人&#xff0c;求二叉树所有节点上的人都接收到悄悄话花费的时间。 输入描述 …

LeetCode刷题----day6(1)

转载自该文章https://programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 链表基础 什么是链表 链表是一种通过指针串联在一起的线性结构&#xff0c;每一个节点由两部分组成&#xff0c;一个是数据域一个是指针域&#xff08;存放指向下一个…

挑战杯 基于卷积神经网络的乳腺癌分类 深度学习 医学图像

文章目录 1 前言2 前言3 数据集3.1 良性样本3.2 病变样本 4 开发环境5 代码实现5.1 实现流程5.2 部分代码实现5.2.1 导入库5.2.2 图像加载5.2.3 标记5.2.4 分组5.2.5 构建模型训练 6 分析指标6.1 精度&#xff0c;召回率和F1度量6.2 混淆矩阵 7 结果和结论8 最后 1 前言 &…

基于大数据的智能家居销量数据分析

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

vue : 无法加载文件 C:\Program Files\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本。

解决方法&#xff1a; 打开PowerShell&#xff0c;在命令框输入set-ExecutionPolicy RemoteSigned 在PowerShell中输入会出现如下图&#xff0c;输入y即可。

数据结构链表力扣例题AC(3)——代码以及思路记录

160. 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 AC写法一 struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {//思…

Nginx跳转模块之rewrite

一.location与rewrite模块的区别 rewrite&#xff1a;对访问的域名或者域名内的URL路径地址重写 location&#xff1a;对访问的路径做访问控制或者代理转发 二.rewrite模块基本内容 1.功能 通过正则表达式的匹配来改变URI&#xff0c;可以同时存在一个或多个指令&#xff0c…

echarts:显示图例(销量1、销量2)

1、代码 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>Insert title here</title> </head> <body> <div id"main" style"width: 600px;height:400px;"></div> &l…

了解网络延迟-MDN文档学习笔记

了解延迟 查看更多学习笔记&#xff1a;GitHub&#xff1a;LoveEmiliaForever MDN中文官网 CDN CDN (内容分发网络) 指的是一组分布在各个地区的服务器 这些服务器存储着数据的副本&#xff0c;因此服务器可以根据哪些服务器与用户距离最近&#xff0c;来满足数据的请求 CD…

kubernetes的网络flannel与caclio

flannel网络 跨主机通信的一个解决方案是Flannel&#xff0c;由CoreOS推出&#xff0c;支持3种实现&#xff1a;UDP、VXLAN、host-gw udp模式&#xff1a;使用设备flannel.0进行封包解包&#xff0c;不是内核原生支持&#xff0c;上下文切换较大&#xff0c;性能非常差 vxlan模…

NestJS入门7:增加异常过滤器

前文参考&#xff1a; NestJS入门1 NestJS入门2&#xff1a;创建模块 NestJS入门3&#xff1a;不同请求方式前后端写法 NestJS入门4&#xff1a;MySQL typeorm 增删改查 NestJS入门5&#xff1a;加入Swagger NestJS入门6&#xff1a;日志中间件 本文代码基于上一篇文章《…

C语言实现直接插入排序

直接插入排序 其平均复杂度是 O(n2)&#xff0c;因此应用场景较少。 接插入排序的思路是&#xff1a; 每次处理一个数据&#xff0c;将其插入到一个已经排好序的子序列中&#xff0c;直到数据处理完毕。 下面给出一个动画示例&#xff1a; 这里写图片描述&#xff1a;从上面来…