diff --git a/tuntap/addr.go b/tuntap/addr.go new file mode 100644 index 0000000..40c395c --- /dev/null +++ b/tuntap/addr.go @@ -0,0 +1,31 @@ +package tuntap + +import ( + "net" + + "github.com/vishvananda/netlink" +) + +// An Addr represents an IP address and its associated routing prefix. +type Addr netlink.Addr + +// ParseCIDR parses s as a CIDR notation IP address and prefix length. +func ParseCIDR(s string) (*Addr, error) { + ip, ipNet, err := net.ParseCIDR(s) + if err != nil { + return nil, err + } + ipNet.IP = ip + + return &Addr{IPNet: ipNet}, nil +} + +// Network returns the network name, "ip+net". +func (addr *Addr) Network() string { + return addr.IPNet.Network() +} + +// String returns the CIDR notation of the address. +func (addr *Addr) String() string { + return addr.IPNet.String() +} diff --git a/tuntap/device.go b/tuntap/device.go index 219ee9c..a352e44 100644 --- a/tuntap/device.go +++ b/tuntap/device.go @@ -87,3 +87,44 @@ func (dev *Device) SetMTU(mtu int) error { return netlink.LinkSetMTU(link, mtu) } + +// Addrs returns all IPv4 and IPv6 addresses assigned to the interface. +func (dev *Device) Addrs() ([]*Addr, error) { + link, err := netlink.LinkByIndex(dev.Index) + if err != nil { + return nil, err + } + list, err := netlink.AddrList(link, netlink.FAMILY_ALL) + if err != nil { + return nil, err + } + + addrs := make([]*Addr, len(list)) + for i := range list { + a := Addr(list[i]) + addrs[i] = &a + } + return addrs, nil +} + +// AddAddr adds the specified IP address to the interface. +func (dev *Device) AddAddr(addr *Addr) error { + link, err := netlink.LinkByIndex(dev.Index) + if err != nil { + return err + } + + a := netlink.Addr(*addr) + return netlink.AddrAdd(link, &a) +} + +// DelAddr removes the specified IP address from the interface. +func (dev *Device) DelAddr(addr *Addr) error { + link, err := netlink.LinkByIndex(dev.Index) + if err != nil { + return err + } + + a := netlink.Addr(*addr) + return netlink.AddrDel(link, &a) +}