mirror of
https://github.com/h44z/wg-portal.git
synced 2025-12-15 11:06:17 +00:00
WIP: support for multiple WireGuard devices (#2)
This commit is contained in:
122
internal/wireguard/manager_net.go
Normal file
122
internal/wireguard/manager_net.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package wireguard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/milosgajdos/tenus"
|
||||
)
|
||||
|
||||
const DefaultMTU = 1420
|
||||
|
||||
func (m *Manager) GetIPAddress(device string) ([]string, error) {
|
||||
wgInterface, err := tenus.NewLinkFrom(device)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not retrieve WireGuard interface %s", device)
|
||||
}
|
||||
|
||||
// Get golang net.interface
|
||||
iface := wgInterface.NetInterface()
|
||||
if iface == nil { // Not sure if this check is really necessary
|
||||
return nil, errors.Wrap(err, "could not retrieve WireGuard net.interface")
|
||||
}
|
||||
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve WireGuard ip addresses")
|
||||
}
|
||||
|
||||
ipAddresses := make([]string, 0, len(addrs))
|
||||
for _, addr := range addrs {
|
||||
var ip net.IP
|
||||
var mask net.IPMask
|
||||
switch v := addr.(type) {
|
||||
case *net.IPNet:
|
||||
ip = v.IP
|
||||
mask = v.Mask
|
||||
case *net.IPAddr:
|
||||
ip = v.IP
|
||||
mask = ip.DefaultMask()
|
||||
}
|
||||
if ip == nil || mask == nil {
|
||||
continue // something is wrong?
|
||||
}
|
||||
|
||||
maskSize, _ := mask.Size()
|
||||
cidr := fmt.Sprintf("%s/%d", ip.String(), maskSize)
|
||||
ipAddresses = append(ipAddresses, cidr)
|
||||
}
|
||||
|
||||
return ipAddresses, nil
|
||||
}
|
||||
|
||||
func (m *Manager) SetIPAddress(device string, cidrs []string) error {
|
||||
wgInterface, err := tenus.NewLinkFrom(device)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not retrieve WireGuard interface %s", device)
|
||||
}
|
||||
|
||||
// First remove existing IP addresses
|
||||
existingIPs, err := m.GetIPAddress(device)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve IP addresses")
|
||||
}
|
||||
for _, cidr := range existingIPs {
|
||||
wgIp, wgIpNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to parse cidr %s", cidr)
|
||||
}
|
||||
|
||||
if err := wgInterface.UnsetLinkIp(wgIp, wgIpNet); err != nil {
|
||||
return errors.Wrapf(err, "failed to unset ip %s", cidr)
|
||||
}
|
||||
}
|
||||
|
||||
// Next set new IP addresses
|
||||
for _, cidr := range cidrs {
|
||||
wgIp, wgIpNet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unable to parse cidr %s", cidr)
|
||||
}
|
||||
|
||||
if err := wgInterface.SetLinkIp(wgIp, wgIpNet); err != nil {
|
||||
return errors.Wrapf(err, "failed to set ip %s", cidr)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) GetMTU(device string) (int, error) {
|
||||
wgInterface, err := tenus.NewLinkFrom(device)
|
||||
if err != nil {
|
||||
return 0, errors.Wrapf(err, "could not retrieve WireGuard interface %s", device)
|
||||
}
|
||||
|
||||
// Get golang net.interface
|
||||
iface := wgInterface.NetInterface()
|
||||
if iface == nil { // Not sure if this check is really necessary
|
||||
return 0, errors.Wrap(err, "could not retrieve WireGuard net.interface")
|
||||
}
|
||||
|
||||
return iface.MTU, nil
|
||||
}
|
||||
|
||||
func (m *Manager) SetMTU(device string, mtu int) error {
|
||||
wgInterface, err := tenus.NewLinkFrom(device)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not retrieve WireGuard interface %s", device)
|
||||
}
|
||||
|
||||
if mtu == 0 {
|
||||
mtu = DefaultMTU
|
||||
}
|
||||
|
||||
if err := wgInterface.SetLinkMTU(mtu); err != nil {
|
||||
return errors.Wrapf(err, "could not set MTU on interface %s", device)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user