iface.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package ip
  2. import (
  3. "errors"
  4. "net"
  5. "syscall"
  6. "github.com/coreos/flannel/Godeps/_workspace/src/github.com/vishvananda/netlink"
  7. )
  8. func GetIfaceIP4Addr(iface *net.Interface) (net.IP, error) {
  9. addrs, err := iface.Addrs()
  10. if err != nil {
  11. return nil, err
  12. }
  13. // prefer non link-local addr
  14. var ll net.IP
  15. for _, addr := range addrs {
  16. // Attempt to parse the address in CIDR notation
  17. // and assert it is IPv4
  18. ip, _, err := net.ParseCIDR(addr.String())
  19. if err != nil || ip.To4() == nil {
  20. continue
  21. }
  22. if ip.IsGlobalUnicast() {
  23. return ip, nil
  24. }
  25. if ip.IsLinkLocalUnicast() {
  26. ll = ip
  27. }
  28. }
  29. if ll != nil {
  30. // didn't find global but found link-local. it'll do.
  31. return ll, nil
  32. }
  33. return nil, errors.New("No IPv4 address found for given interface")
  34. }
  35. func GetIfaceIP4AddrMatch(iface *net.Interface, matchAddr net.IP) error {
  36. addrs, err := iface.Addrs()
  37. if err != nil {
  38. return err
  39. }
  40. for _, addr := range addrs {
  41. // Attempt to parse the address in CIDR notation
  42. // and assert it is IPv4
  43. ip, _, err := net.ParseCIDR(addr.String())
  44. if err == nil && ip.To4() != nil {
  45. if ip.To4().Equal(matchAddr) {
  46. return nil
  47. }
  48. }
  49. }
  50. return errors.New("No IPv4 address found for given interface")
  51. }
  52. func GetDefaultGatewayIface() (*net.Interface, error) {
  53. routes, err := netlink.RouteList(nil, syscall.AF_INET)
  54. if err != nil {
  55. return nil, err
  56. }
  57. for _, route := range routes {
  58. if route.Dst == nil || route.Dst.String() == "0.0.0.0/0" {
  59. if route.LinkIndex <= 0 {
  60. return nil, errors.New("Found default route but could not determine interface")
  61. }
  62. return net.InterfaceByIndex(route.LinkIndex)
  63. }
  64. }
  65. return nil, errors.New("Unable to find default route")
  66. }
  67. func GetInterfaceByIP(ip net.IP) (*net.Interface, error) {
  68. ifaces, err := net.Interfaces()
  69. if err != nil {
  70. return nil, err
  71. }
  72. for _, iface := range ifaces {
  73. err := GetIfaceIP4AddrMatch(&iface, ip)
  74. if err == nil {
  75. return &iface, nil
  76. }
  77. }
  78. return nil, errors.New("No interface with given IP found")
  79. }