netutils.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package arping
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. )
  7. func findIPInNetworkFromIface(dstIP net.IP, iface net.Interface) (net.IP, error) {
  8. addrs, err := iface.Addrs()
  9. if err != nil {
  10. return nil, err
  11. }
  12. for _, a := range addrs {
  13. if ipnet, ok := a.(*net.IPNet); ok {
  14. if ipnet.Contains(dstIP) {
  15. return ipnet.IP, nil
  16. }
  17. }
  18. }
  19. return nil, fmt.Errorf("iface: '%s' can't reach ip: '%s'", iface.Name, dstIP)
  20. }
  21. func findUsableInterfaceForNetwork(dstIP net.IP) (*net.Interface, error) {
  22. ifaces, err := net.Interfaces()
  23. if err != nil {
  24. return nil, err
  25. }
  26. isDown := func(iface net.Interface) bool {
  27. return iface.Flags&1 == 0
  28. }
  29. hasAddressInNetwork := func(iface net.Interface) bool {
  30. if _, err := findIPInNetworkFromIface(dstIP, iface); err != nil {
  31. return false
  32. }
  33. return true
  34. }
  35. verboseLog.Println("search usable interface")
  36. logIfaceResult := func(msg string, iface net.Interface) {
  37. verboseLog.Printf("%10s: %6s %18s %s", msg, iface.Name, iface.HardwareAddr, iface.Flags)
  38. }
  39. for _, iface := range ifaces {
  40. if isDown(iface) {
  41. logIfaceResult("DOWN", iface)
  42. continue
  43. }
  44. if !hasAddressInNetwork(iface) {
  45. logIfaceResult("OTHER NET", iface)
  46. continue
  47. }
  48. logIfaceResult("USABLE", iface)
  49. return &iface, nil
  50. }
  51. return nil, errors.New("no usable interface found")
  52. }