2021-05-01 12:45:37 +02:00
|
|
|
package iface
|
|
|
|
|
2021-06-24 11:46:33 +02:00
|
|
|
import (
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl"
|
|
|
|
"net"
|
2022-01-17 14:01:58 +01:00
|
|
|
"os"
|
|
|
|
"runtime"
|
2021-06-24 11:46:33 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2022-05-08 11:04:57 +02:00
|
|
|
DefaultMTU = 1280
|
2022-03-01 14:07:33 +01:00
|
|
|
DefaultWgPort = 51820
|
2021-06-24 11:46:33 +02:00
|
|
|
)
|
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
// WGIface represents a interface instance
|
|
|
|
type WGIface struct {
|
|
|
|
Name string
|
|
|
|
Port int
|
|
|
|
MTU int
|
|
|
|
Address WGAddress
|
|
|
|
Interface NetInterface
|
|
|
|
}
|
2021-06-24 11:46:33 +02:00
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
// WGAddress Wireguard parsed address
|
|
|
|
type WGAddress struct {
|
|
|
|
IP net.IP
|
|
|
|
Network *net.IPNet
|
|
|
|
}
|
2021-06-24 11:46:33 +02:00
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
// NetInterface represents a generic network tunnel interface
|
|
|
|
type NetInterface interface {
|
|
|
|
Close() error
|
2021-06-24 11:46:33 +02:00
|
|
|
}
|
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
// NewWGIface Creates a new Wireguard interface instance
|
|
|
|
func NewWGIface(iface string, address string, mtu int) (WGIface, error) {
|
|
|
|
wgIface := WGIface{
|
|
|
|
Name: iface,
|
|
|
|
MTU: mtu,
|
2021-06-24 11:46:33 +02:00
|
|
|
}
|
2021-07-19 15:02:11 +02:00
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
wgAddress, err := parseAddress(address)
|
2021-07-19 15:02:11 +02:00
|
|
|
if err != nil {
|
2022-01-17 14:01:58 +01:00
|
|
|
return wgIface, err
|
2021-07-19 15:02:11 +02:00
|
|
|
}
|
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
wgIface.Address = wgAddress
|
|
|
|
|
|
|
|
return wgIface, nil
|
2021-06-24 11:46:33 +02:00
|
|
|
}
|
|
|
|
|
2021-08-15 16:56:26 +02:00
|
|
|
// Exists checks whether specified Wireguard device exists or not
|
|
|
|
func Exists(iface string) (*bool, error) {
|
|
|
|
wg, err := wgctrl.New()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer wg.Close()
|
|
|
|
|
|
|
|
devices, err := wg.Devices()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var exists bool
|
|
|
|
for _, d := range devices {
|
|
|
|
if d.Name == iface {
|
|
|
|
exists = true
|
|
|
|
return &exists, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
exists = false
|
|
|
|
return &exists, nil
|
|
|
|
}
|
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
// parseAddress parse a string ("1.2.3.4/24") address to WG Address
|
|
|
|
func parseAddress(address string) (WGAddress, error) {
|
|
|
|
ip, network, err := net.ParseCIDR(address)
|
2021-06-24 11:46:33 +02:00
|
|
|
if err != nil {
|
2022-01-17 14:01:58 +01:00
|
|
|
return WGAddress{}, err
|
2021-06-24 11:46:33 +02:00
|
|
|
}
|
2022-01-17 14:01:58 +01:00
|
|
|
return WGAddress{
|
|
|
|
IP: ip,
|
|
|
|
Network: network,
|
|
|
|
}, nil
|
2021-06-24 11:46:33 +02:00
|
|
|
}
|
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
// Closes the tunnel interface
|
|
|
|
func (w *WGIface) Close() error {
|
2021-06-24 11:46:33 +02:00
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
err := w.Interface.Close()
|
2021-06-24 11:46:33 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-01-17 14:01:58 +01:00
|
|
|
if runtime.GOOS == "darwin" {
|
|
|
|
sockPath := "/var/run/wireguard/" + w.Name + ".sock"
|
|
|
|
if _, statErr := os.Stat(sockPath); statErr == nil {
|
|
|
|
statErr = os.Remove(sockPath)
|
|
|
|
if statErr != nil {
|
|
|
|
return statErr
|
|
|
|
}
|
|
|
|
}
|
2021-06-24 11:46:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|