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启动的 ...
随机推荐
- redis,rabbitmq,SqlAlchemy
redis发布和订阅
- SpringBoot动态注入Bean
目的: 在程序运行期间,动态添加Bean进入到Spring容器. 目前使用到的场景: 对当当网的ElasticJob进行封装,通过自定义注解@ElasticJob的方式开启分布式定时任务. 当所有的B ...
- PHP preg_filter() 函数
preg_filter 函数用于执行一个正则表达式搜索和替换.高佣联盟 www.cgewang.com 语法 mixed preg_filter ( mixed $pattern , mixed $r ...
- PHP imagecolorallocate - 为一幅图像分配颜色
imagecolorallocate — 为一幅图像分配颜色.高佣联盟 www.cgewang.com 语法 int imagecolorallocate ( resource $image , in ...
- 7.9 NOI模拟赛 C.走路 背包 dp 特异性
(啊啊啊 什么考试的时候突然降智这题目硬生生没想出来. 容易发现是先走到某个地方 然后再走回来的 然后在倒着走的路径上选择一些点使得最后的得到的最多. 设\(f_{i,j}\)表示到达i这个点选择的价 ...
- intel:spectre&Meltdown侧信道攻击(四)—— cache mapping
前面简单介绍了row hammer攻击的原理和方法,为了更好理解这种底层硬件类攻击,今天介绍一下cpu的cache mapping: 众所周知,cpu从内存读数据,最开始用的是虚拟地址,需要通过分页机 ...
- 文件操作之File 和 Path
转载:https://blog.csdn.net/u010889616/article/details/52694061 Java7中文件IO发生了很大的变化,专门引入了很多新的类: import j ...
- win10下visual studio code安装及mingw C/C++编译器配置,launch.json和task.json文件的配置
快一年了,我竟然还有脸回来..... 过去一年,由于毕设.找工作的原因,发生太多变故,所以一直没更(最主要的原因还是毅力不够...),至于发生了什么事,以后想说的时候再更吧..依然是小白,下面说正事. ...
- 畅购商城(五):Elasticsearch实现商品搜索
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 畅购商城(一):环境搭建 畅购商 ...
- LVS-DR:搭建HTTP和HTTPS负载均衡集群
目录 LVS-DR实战:搭建HTTP和HTTPS负载均衡集群 1. 搭建lvs-dr模式的http负载集群 1.1 LVS上配置IP 1.2 RS上配置arp内核参数 1.3 RS上配置VIP 1.4 ...