| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- package handler
- import (
- "fmt"
- "net"
- "os"
- "strings"
- "syscall"
- "unsafe"
- "github.com/bjdgyc/anylink/base"
- "github.com/bjdgyc/anylink/pkg/utils"
- "github.com/bjdgyc/anylink/sessdata"
- )
- // link vtap
- const vTapPrefix = "lvtap"
- type Vtap struct {
- *os.File
- ifName string
- }
- func (v *Vtap) Close() error {
- v.File.Close()
- cmdstr := fmt.Sprintf("ip link del %s", v.ifName)
- return execCmd([]string{cmdstr})
- }
- func checkMacvtap() {
- _setGateway()
- _checkTapIp(base.Cfg.Ipv4Master)
- ifName := "anylinkMacvtap"
- // 加载 macvtap
- cmdstr0 := fmt.Sprintln("modprobe -i macvtap")
- // 开启主网卡混杂模式
- cmdstr1 := fmt.Sprintf("ip link set dev %s promisc on", base.Cfg.Ipv4Master)
- // 测试 macvtap 功能
- cmdstr2 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, ifName)
- cmdstr3 := fmt.Sprintf("ip link del %s", ifName)
- err := execCmd([]string{cmdstr0, cmdstr1, cmdstr2, cmdstr3})
- if err != nil {
- base.Fatal(err)
- }
- }
- // 创建 Macvtap 网卡
- func LinkMacvtap(cSess *sessdata.ConnSession) error {
- capL := sessdata.IpPool.IpLongMax - sessdata.IpPool.IpLongMin
- ipN := utils.Ip2long(cSess.IpAddr) % capL
- ifName := fmt.Sprintf("%s%d", vTapPrefix, ipN)
- cSess.SetIfName(ifName)
- cmdstr1 := fmt.Sprintf("ip link add link %s name %s type macvtap mode bridge", base.Cfg.Ipv4Master, ifName)
- cmdstr2 := fmt.Sprintf("ip link set dev %s up mtu %d address %s", ifName, cSess.Mtu, cSess.MacHw)
- err := execCmd([]string{cmdstr1, cmdstr2})
- if err != nil {
- base.Error(err)
- return err
- }
- cmdstr3 := fmt.Sprintf("sysctl -w net.ipv6.conf.%s.disable_ipv6=1", ifName)
- execCmd([]string{cmdstr3})
- return createVtap(cSess, ifName)
- }
- // func checkIpvtap() {
- // }
- // 创建 Ipvtap 网卡
- func LinkIpvtap(cSess *sessdata.ConnSession) error {
- return nil
- }
- type ifReq struct {
- Name [0x10]byte
- Flags uint16
- pad [0x28 - 0x10 - 2]byte
- }
- func createVtap(cSess *sessdata.ConnSession, ifName string) error {
- // 初始化 ifName
- inf, err := net.InterfaceByName(ifName)
- if err != nil {
- base.Error(err)
- return err
- }
- tName := fmt.Sprintf("/dev/tap%d", inf.Index)
- var fdInt int
- fdInt, err = syscall.Open(tName, syscall.O_RDWR|syscall.O_NONBLOCK, 0)
- if err != nil {
- return err
- }
- var flags uint16 = syscall.IFF_TAP | syscall.IFF_NO_PI
- var req ifReq
- req.Flags = flags
- _, _, errno := syscall.Syscall(
- syscall.SYS_IOCTL,
- uintptr(fdInt),
- uintptr(syscall.TUNSETIFF),
- uintptr(unsafe.Pointer(&req)),
- )
- if errno != 0 {
- return os.NewSyscallError("ioctl", errno)
- }
- file := os.NewFile(uintptr(fdInt), tName)
- ifce := &Vtap{file, ifName}
- go allTapRead(ifce, cSess)
- go allTapWrite(ifce, cSess)
- return nil
- }
- // 销毁未关闭的vtap
- func destroyVtap() {
- its, err := net.Interfaces()
- if err != nil {
- base.Error(err)
- return
- }
- for _, v := range its {
- if strings.HasPrefix(v.Name, vTapPrefix) {
- // 删除原来的网卡
- cmdstr := fmt.Sprintf("ip link del %s", v.Name)
- execCmd([]string{cmdstr})
- }
- }
- }
|