mirror of
https://github.com/fumiama/water.git
synced 2026-06-28 07:50:25 +08:00
add wintun support
This commit is contained in:
1
go.mod
1
go.mod
@@ -5,4 +5,5 @@ go 1.17
|
|||||||
require (
|
require (
|
||||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
|
||||||
|
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224
|
||||||
)
|
)
|
||||||
|
|||||||
3
go.sum
3
go.sum
@@ -1,4 +1,7 @@
|
|||||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
|
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
|
||||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
|
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
|
||||||
|
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
|
||||||
|
golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/windows/registry"
|
"golang.org/x/sys/windows/registry"
|
||||||
|
"golang.zx2c4.com/wintun"
|
||||||
)
|
)
|
||||||
|
|
||||||
// To use it with windows, you need a tap driver installed on windows.
|
// To use it with windows, you need a tap driver installed on windows.
|
||||||
@@ -209,33 +210,7 @@ func setStatus(fd syscall.Handle, status bool) error {
|
|||||||
return syscall.DeviceIoControl(fd, tap_ioctl_set_media_status, &code[0], uint32(4), &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
|
return syscall.DeviceIoControl(fd, tap_ioctl_set_media_status, &code[0], uint32(4), &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setTUN is used to configure the IP address in the underlying driver when using TUN
|
func openTap(config Config) (ifce *Interface, err error) {
|
||||||
func setTUN(fd syscall.Handle, network string) error {
|
|
||||||
var bytesReturned uint32
|
|
||||||
rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
|
|
||||||
|
|
||||||
localIP, remoteNet, err := net.ParseCIDR(network)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Failed to parse network CIDR in config, %v", err)
|
|
||||||
}
|
|
||||||
if localIP.To4() == nil {
|
|
||||||
return fmt.Errorf("Provided network(%s) is not a valid IPv4 address", network)
|
|
||||||
}
|
|
||||||
code2 := make([]byte, 0, 12)
|
|
||||||
code2 = append(code2, localIP.To4()[:4]...)
|
|
||||||
code2 = append(code2, remoteNet.IP.To4()[:4]...)
|
|
||||||
code2 = append(code2, remoteNet.Mask[:4]...)
|
|
||||||
if len(code2) != 12 {
|
|
||||||
return fmt.Errorf("Provided network(%s) is not valid", network)
|
|
||||||
}
|
|
||||||
if err := syscall.DeviceIoControl(fd, tap_ioctl_config_tun, &code2[0], uint32(12), &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// openDev find and open an interface.
|
|
||||||
func openDev(config Config) (ifce *Interface, err error) {
|
|
||||||
// find the device in registry.
|
// find the device in registry.
|
||||||
deviceid, err := getdeviceid(config.PlatformSpecificParams.ComponentID, config.PlatformSpecificParams.InterfaceName)
|
deviceid, err := getdeviceid(config.PlatformSpecificParams.ComponentID, config.PlatformSpecificParams.InterfaceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -281,13 +256,6 @@ func openDev(config Config) (ifce *Interface, err error) {
|
|||||||
fd := &wfile{fd: file, ro: ro, wo: wo}
|
fd := &wfile{fd: file, ro: ro, wo: wo}
|
||||||
ifce = &Interface{isTAP: (config.DeviceType == TAP), ReadWriteCloser: fd}
|
ifce = &Interface{isTAP: (config.DeviceType == TAP), ReadWriteCloser: fd}
|
||||||
|
|
||||||
//TUN
|
|
||||||
if config.DeviceType == TUN {
|
|
||||||
if err := setTUN(file, config.PlatformSpecificParams.Network); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// bring up device.
|
// bring up device.
|
||||||
if err := setStatus(file, true); err != nil {
|
if err := setStatus(file, true); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -311,3 +279,70 @@ func openDev(config Config) (ifce *Interface, err error) {
|
|||||||
|
|
||||||
return nil, errIfceNameNotFound
|
return nil, errIfceNameNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type wintunRWC struct {
|
||||||
|
ad *wintun.Adapter
|
||||||
|
s wintun.Session
|
||||||
|
readmu sync.Mutex
|
||||||
|
readbuf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wintunRWC) Close() error {
|
||||||
|
w.s.End()
|
||||||
|
return w.ad.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wintunRWC) Write(b []byte) (int, error) {
|
||||||
|
w.s.SendPacket(b)
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *wintunRWC) Read(b []byte) (int, error) {
|
||||||
|
w.readmu.Lock()
|
||||||
|
defer w.readmu.Unlock()
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
|
||||||
|
if w.readbuf != nil {
|
||||||
|
n = copy(b, w.readbuf)
|
||||||
|
if len(w.readbuf) >= len(b) {
|
||||||
|
w.readbuf = w.readbuf[len(b):]
|
||||||
|
if len(w.readbuf) == 0 {
|
||||||
|
w.readbuf = nil
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
b = b[len(w.readbuf):]
|
||||||
|
w.readbuf = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
packet, err := w.s.ReceivePacket()
|
||||||
|
if err != nil {
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
n += copy(b, packet)
|
||||||
|
if len(packet) > len(b) {
|
||||||
|
w.readbuf = packet[len(b):]
|
||||||
|
}
|
||||||
|
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// openDev find and open an interface.
|
||||||
|
func openDev(config Config) (ifce *Interface, err error) {
|
||||||
|
// TAP
|
||||||
|
if config.DeviceType == TAP {
|
||||||
|
return openTap(config)
|
||||||
|
}
|
||||||
|
// TUN
|
||||||
|
ad, err := wintun.OpenAdapter(config.InterfaceName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s, err := ad.StartSession(65536)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Interface{ReadWriteCloser: &wintunRWC{s: s, ad: ad}, name: config.InterfaceName}, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user