golang 创建 tun 设备
源码:
package main import (
"flag"
"fmt"
"github.com/pkg/errors"
"net"
"os"
"syscall"
"unsafe"
)
var (
HostName, _ = os.Hostname()
ETH_P_ARP = 0x0806
AF_INET = int32()
AF_INET6 = int32()
AF_BRIDGE = int32()
) func Htons(i uint16) uint16 {
return (i<<)&0xff00 | i>>
} type intfReq struct {
name []byte
flags uint16
} // sendIOCtlMessage ioctl system call
func sendIOCtlMessage(fd uintptr, request uintptr, ifReq uintptr) error {
fmt.Printf("syscall fd %+v, request %+v, ifReq %+v", fd, request, ifReq)
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, request, ifReq)
if errno != {
fmt.Printf("Fail to execute ioctl, the errno is %+v", errno)
return errors.New("failed execute ioctl")
}
return nil
} // sendFCtlMessage fcntl system call
func sendFCtlMessage(fd int, cmd int, arg int) error {
_, _, err := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
if err != {
fmt.Printf("Fail to execute fctl, the error is %+v", err)
return errors.New("failed execute fctl")
}
return nil
}
var tunDevicePath = "/dev/net/tun"
func main() {
var DeviceName string
flag.StringVar(&DeviceName, "name", "", "pkt0")
flag.Parse()
flag.Usage() fd, err := syscall.Open(tunDevicePath, os.O_RDWR, )
if err != nil {
fmt.Printf("failed to open tun device: %+v", err)
return
} var req intfReq
req.flags = syscall.IFF_TAP | syscall.IFF_NO_PI
copy(req.name[:], DeviceName) if err := sendIOCtlMessage(uintptr(fd),
uintptr(syscall.TUNSETIFF),
uintptr(unsafe.Pointer(&req))); err != nil {
return
}
if err := sendFCtlMessage(fd, syscall.F_SETFD, syscall.FD_CLOEXEC); err != nil {
return
}
if err := sendIOCtlMessage(uintptr(fd), syscall.TUNSETPERSIST, ); err != nil {
return
} raw, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(Htons(syscall.ETH_P_ALL)))
if err != nil {
fmt.Printf("failed to create RAW socket: %+v", err)
return
} var reqRaw intfReq
copy(reqRaw.name[:], DeviceName)
if err := sendIOCtlMessage(uintptr(raw),
syscall.SIOCGIFINDEX,
uintptr(unsafe.Pointer(&reqRaw))); err != nil {
return
} ifi, err := net.InterfaceByName(DeviceName)
if err != nil {
fmt.Printf("failed to get device: %+v", err)
return
} if err := syscall.Bind(raw, &syscall.SockaddrLinklayer{
Protocol: uint16(Htons(syscall.ETH_P_ALL)),
Ifindex: ifi.Index,
}); err != nil {
fmt.Printf("failed to bind: %+v", err)
return
}
if err := sendIOCtlMessage(uintptr(raw),
syscall.SIOCSIFTXQLEN, uintptr(unsafe.Pointer(&reqRaw))); err != nil {
return
}
if err := sendIOCtlMessage(uintptr(raw),
syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&reqRaw))); err != nil {
return
}
reqRaw.flags = syscall.IFF_UP if err := sendIOCtlMessage(uintptr(raw),
syscall.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&reqRaw))); err != nil {
return
} var r intfReq
copy(r.name[:], DeviceName)
if err := sendIOCtlMessage(uintptr(raw),
syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&r))); err != nil {
return
} if err := syscall.Close(raw); err != nil {
fmt.Printf("failed to close RAW socket: %+v", err)
return
} return
}
运行结果:
[root@wangjq tun]# ./main -name demo
Usage of ./main:
-name string
pkt0
syscall fd , request , ifReq
syscall fd , request , ifReq
syscall fd , request , ifReq
syscall fd , request , ifReq
syscall fd , request , ifReq
syscall fd , request , ifReq
syscall fd , request , ifReq
[root@wangjq tun]# ip link show demo
: demo: <NO-CARRIER,BROADCAST,UP> mtu qdisc pfifo_fast state DOWN mode DEFAULT group default qlen
link/ether 7e:e7::ad:f7:9e brd ff:ff:ff:ff:ff:ff
golang 创建 tun 设备的更多相关文章
- Linux 网络工具详解之 ip tuntap 和 tunctl 创建 tap/tun 设备
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 在前面一篇文章 ...
- 【转】Linux 网络工具详解之 ip tuntap 和 tunctl 创建 tap/tun 设备
原文:https://www.cnblogs.com/bakari/p/10449664.html -------------------------------------------------- ...
- 使用 TUN 设备实现一个简单的 UDP 代理隧道
若要实现在 Linux 下的代理程序,方法有很多,比如看着 RFC 1928 来实现一个 socks5 代理并自行设置程序经过 socks5 代理等方式,下文是使用 Linux 提供的 tun/tap ...
- 代码片段 - Golang 创建 .tar.gz 压缩包
Golang创建 .tar.gz 压缩包 tar 包实现了文件的打包功能,可以将多个文件或目录存储到单一的 .tar 文件中,tar 本身不具有压缩功能,只能打包文件或目录: import " ...
- Sybase ASE安装过程报错,无法创建数据库设备[AM fork() failed]
今天同事要搭建一套测试环境,安装开发版的SYBASE ASE 15.03 Windows平台下的,发现安装过程中到了创建数据库设备的环节就开始报错了,报错信息如下: 03/24/14 09:31:44 ...
- D3D游戏降帧的动态创建D3D设备以及ShellCode HOOK玩法
欢迎转载,转载请注明出处:http://blog.csdn.net/gnorth/article/details/9327971 说白了,也就是HOOK掉Present,这种代码,其实百度上某些地方有 ...
- 自动创建字符设备,不需mknod
自动创建设备文件 1.自动创建设备文件的流程 字符设备驱动模块 -->创建一个设备驱动class--->创建属于class的device--->调用mdev工具(自动完成)--> ...
- linux之misc及使用misc创建字符设备
1:linux字符设备及udev 1.1字符设备 字符设备就是:一个一个字节来进行访问的,不能对字符设备进行随机读写.简单字符设备创建实例如下: #include <linux/module.h ...
- -bash: 无法为立即文档创建临时文件: 设备上没有空间---记一次报错
故障发生原因 测试环境,之前用该机器做过docker-compose,后来有需要用到该机器上的docker环境,需要将旧的docker容器全部删除,由于之前启动是使用docker-compose启动的 ...
随机推荐
- 金字塔卷积:Pyramidal Convolution
论文地址:https://arxiv.org/pdf/2006.11538.pdf github:https://github.com/iduta/pyconv 作者认为,当前CNN主要存在两个不足: ...
- three.js 数学方法之Matrix4
今天郭先生说一说three.js中的Matrix4,相较于Matrix3来说,Matrix4和three.js联系的更紧密,因为在4x4矩阵最常用的用法是作为一个变换矩阵.这使得表示三维空间中的一个点 ...
- three.js 制作一个三维的推箱子游戏
今天郭先生发现大家更喜欢看我发的three.js小作品,今天我就发一个3d版本推箱子的游戏,其实webGL有很多框架,three.js并不合适做游戏引擎,但是可以尝试一些小游戏.在线案例请点击博客原文 ...
- python数据处理书pdf版本|内附网盘链接直接提取|
Python数据处理采用基于项目的方法,介绍用Python完成数据获取.数据清洗.数据探索.数据呈现.数据规模化和自动化的过程.主要内容包括:Python基础知识,如何从CSV.Excel.XML.J ...
- Python 为什么会有个奇怪的“...”对象?
本文出自"Python为什么"系列,请查看全部文章 在写上一篇<Python 为什么要有 pass 语句?>时,我想到一种特别的写法,很多人会把它当成 pass 语句的 ...
- .NET三层架构各项目之间的引用关系及如何添加引用?
1.1三层之间的引用 整个.NET框架的项目创建完成之后,在开发之前,还需要建立各个项目之间的引用关系,以便在编写C#业务逻辑代码时调用相关项目的类库. 1.1.1 引用关系规则 .NET三层架构中的 ...
- OAuth2.0-4整合网关
.antMatchers("/**").access("#oauth2.hasScope('scope1')")上面这行代码,只是控制大范围的访问权限,具体到方 ...
- 001_centos7下比特币源码编译安装
今天我们介绍比特币的源码安装过程,是利用编译安装的 首先安装依赖 yum install -y boost-devel qt-devel protobuf-devel qrencode-devel l ...
- 8 Java 条件逻辑语句
生活中,我们经常需要先做判断,然后才决定是否要做某件事情.例如,在上学的时候,如果期末考试成绩在全校能拿到前100名,则奖励一个 iPhone 11 .对于这种“需要先判断条件,条件满足后才执行的情况 ...
- Docker 启动 Nginx
Docker 启动 Nginx 拉取镜像 docker pull nginx:1.17.9 启动步骤 # 创建 nginx 目录 mkdir -p /usr/local/nginx && ...