mirror of
https://gitee.com/konyshe/goodlink.git
synced 2025-09-28 05:22:18 +08:00
103 lines
3.3 KiB
Go
103 lines
3.3 KiB
Go
//go:build linux
|
||
|
||
package netstack
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"net"
|
||
"os/exec"
|
||
"unsafe"
|
||
|
||
"golang.org/x/sys/unix"
|
||
)
|
||
|
||
func setUnixIP(name string, ip net.IP, mask net.IPMask) error {
|
||
log.Printf("setUnixIP: %s %s %s", name, ip, mask)
|
||
|
||
// 新增接口存在性检查
|
||
if err := checkInterfaceExists(name); err != nil {
|
||
return err
|
||
}
|
||
|
||
// 修改标志位设置流程(先关闭再开启)
|
||
ifreq, _ := unix.NewIfreq(name)
|
||
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(unix.AF_INET), unix.SIOCGIFFLAGS, uintptr(unsafe.Pointer(ifreq)))
|
||
if errno != 0 {
|
||
return fmt.Errorf("SIOCGIFFLAGS(pre-check) failed: %s", unix.ErrnoName(errno))
|
||
}
|
||
originalFlags := ifreq.Uint16()
|
||
|
||
// 临时关闭接口(关键步骤)
|
||
ifreq.SetUint16(originalFlags &^ unix.IFF_UP)
|
||
_, _, errno = unix.Syscall(unix.SYS_IOCTL, uintptr(unix.AF_INET), unix.SIOCSIFFLAGS, uintptr(unsafe.Pointer(ifreq)))
|
||
if errno != 0 {
|
||
return fmt.Errorf("SIOCSIFFLAGS(down) failed: %s", unix.ErrnoName(errno))
|
||
}
|
||
|
||
// 设置IP地址结构体(修复掩码处理)
|
||
addr, _ := unix.NewIfreq(name)
|
||
addr.SetInet4Addr(ip.To4())
|
||
_, _, errno = unix.Syscall(unix.SYS_IOCTL, uintptr(unix.AF_INET), unix.SIOCSIFADDR, uintptr(unsafe.Pointer(addr)))
|
||
if errno != 0 {
|
||
return fmt.Errorf("SIOCSIFADDR failed: %s", unix.ErrnoName(errno)) // 显示具体错误名称
|
||
}
|
||
|
||
// 设置子网掩码(修复变量名错误)
|
||
maskAddr, _ := unix.NewIfreq(name)
|
||
maskAddr.SetInet4Addr(net.IP(mask).To4()) // 显式转换掩码类型
|
||
_, _, errno = unix.Syscall(unix.SYS_IOCTL, uintptr(unix.AF_INET), unix.SIOCSIFNETMASK, uintptr(unsafe.Pointer(maskAddr)))
|
||
if errno != 0 {
|
||
return fmt.Errorf("SIOCSIFNETMASK failed: %s", unix.ErrnoName(errno))
|
||
}
|
||
|
||
// 修改接口激活逻辑(关键修复)
|
||
ifreq, _ = unix.NewIfreq(name)
|
||
ifreq.SetUint16((originalFlags | unix.IFF_UP) &^ unix.IFF_NOARP) // 保留原始标志位并添加UP标志
|
||
_, _, errno = unix.Syscall(unix.SYS_IOCTL, uintptr(unix.AF_INET), unix.SIOCSIFFLAGS, uintptr(unsafe.Pointer(ifreq)))
|
||
if errno != 0 {
|
||
return fmt.Errorf("SIOCSIFFLAGS failed: %s", unix.ErrnoName(errno))
|
||
}
|
||
|
||
log.Printf("Configuration applied successfully")
|
||
return nil
|
||
}
|
||
|
||
// 新增辅助函数
|
||
func checkInterfaceExists(name string) error {
|
||
ifreq, _ := unix.NewIfreq(name)
|
||
_, _, errno := unix.Syscall(unix.SYS_IOCTL, uintptr(unix.AF_INET), unix.SIOCGIFFLAGS, uintptr(unsafe.Pointer(ifreq)))
|
||
if errno != 0 {
|
||
return fmt.Errorf("interface %s not exists: %s", name, unix.ErrnoName(errno))
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// 修改调用端错误处理
|
||
func SetTunIP(wintunEP *Device, ip string, mask int) error {
|
||
// ip addr add 192.17.0.1/32 dev GoodLink
|
||
// ip link set GoodLink up
|
||
// ip route add 192.17.19.1 dev GoodLink
|
||
|
||
// 设置网卡eth0的IP地址为192.168.1.10/24
|
||
cmd := exec.Command("ip", "addr", "add", "192.17.0.1/32", "dev", GetName())
|
||
if err := cmd.Run(); err != nil {
|
||
return err
|
||
}
|
||
|
||
cmd = exec.Command("ip", "link", "set", GetName(), "up")
|
||
if err := cmd.Run(); err != nil {
|
||
return err
|
||
}
|
||
|
||
cmd = exec.Command("ip", "route", "add", GetRemoteIP(), "dev", GetName())
|
||
if err := cmd.Run(); err != nil {
|
||
return err
|
||
}
|
||
|
||
/*if err := setUnixIP(GetName(), net.ParseIP(ip), net.CIDRMask(mask, 32)); err != nil {
|
||
return fmt.Errorf("setUnixIP failed: %w", err)
|
||
}*/
|
||
return nil
|
||
}
|