ifaddr.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package sockaddr
  2. // ifAddrAttrMap is a map of the IfAddr type-specific attributes.
  3. var ifAddrAttrMap map[AttrName]func(IfAddr) string
  4. var ifAddrAttrs []AttrName
  5. func init() {
  6. ifAddrAttrInit()
  7. }
  8. // GetPrivateIP returns a string with a single IP address that is part of RFC
  9. // 6890 and has a default route. If the system can't determine its IP address
  10. // or find an RFC 6890 IP address, an empty string will be returned instead.
  11. // This function is the `eval` equivalent of:
  12. //
  13. // ```
  14. // $ sockaddr eval -r '{{GetPrivateInterfaces | attr "address"}}'
  15. /// ```
  16. func GetPrivateIP() (string, error) {
  17. privateIfs, err := GetPrivateInterfaces()
  18. if err != nil {
  19. return "", err
  20. }
  21. if len(privateIfs) < 1 {
  22. return "", nil
  23. }
  24. ifAddr := privateIfs[0]
  25. ip := *ToIPAddr(ifAddr.SockAddr)
  26. return ip.NetIP().String(), nil
  27. }
  28. // GetPublicIP returns a string with a single IP address that is NOT part of RFC
  29. // 6890 and has a default route. If the system can't determine its IP address
  30. // or find a non RFC 6890 IP address, an empty string will be returned instead.
  31. // This function is the `eval` equivalent of:
  32. //
  33. // ```
  34. // $ sockaddr eval -r '{{GetPublicInterfaces | attr "address"}}'
  35. /// ```
  36. func GetPublicIP() (string, error) {
  37. publicIfs, err := GetPublicInterfaces()
  38. if err != nil {
  39. return "", err
  40. } else if len(publicIfs) < 1 {
  41. return "", nil
  42. }
  43. ifAddr := publicIfs[0]
  44. ip := *ToIPAddr(ifAddr.SockAddr)
  45. return ip.NetIP().String(), nil
  46. }
  47. // GetInterfaceIP returns a string with a single IP address sorted by the size
  48. // of the network (i.e. IP addresses with a smaller netmask, larger network
  49. // size, are sorted first). This function is the `eval` equivalent of:
  50. //
  51. // ```
  52. // $ sockaddr eval -r '{{GetAllInterfaces | include "name" <<ARG>> | sort "type,size" | include "flag" "forwardable" | attr "address" }}'
  53. /// ```
  54. func GetInterfaceIP(namedIfRE string) (string, error) {
  55. ifAddrs, err := GetAllInterfaces()
  56. if err != nil {
  57. return "", err
  58. }
  59. ifAddrs, _, err = IfByName(namedIfRE, ifAddrs)
  60. if err != nil {
  61. return "", err
  62. }
  63. ifAddrs, _, err = IfByFlag("forwardable", ifAddrs)
  64. if err != nil {
  65. return "", err
  66. }
  67. ifAddrs, err = SortIfBy("+type,+size", ifAddrs)
  68. if err != nil {
  69. return "", err
  70. }
  71. if len(ifAddrs) == 0 {
  72. return "", err
  73. }
  74. ip := ToIPAddr(ifAddrs[0].SockAddr)
  75. if ip == nil {
  76. return "", err
  77. }
  78. return IPAddrAttr(*ip, "address"), nil
  79. }
  80. // IfAddrAttrs returns a list of attributes supported by the IfAddr type
  81. func IfAddrAttrs() []AttrName {
  82. return ifAddrAttrs
  83. }
  84. // IfAddrAttr returns a string representation of an attribute for the given
  85. // IfAddr.
  86. func IfAddrAttr(ifAddr IfAddr, attrName AttrName) string {
  87. fn, found := ifAddrAttrMap[attrName]
  88. if !found {
  89. return ""
  90. }
  91. return fn(ifAddr)
  92. }
  93. // ifAddrAttrInit is called once at init()
  94. func ifAddrAttrInit() {
  95. // Sorted for human readability
  96. ifAddrAttrs = []AttrName{
  97. "flags",
  98. "name",
  99. }
  100. ifAddrAttrMap = map[AttrName]func(ifAddr IfAddr) string{
  101. "flags": func(ifAddr IfAddr) string {
  102. return ifAddr.Interface.Flags.String()
  103. },
  104. "name": func(ifAddr IfAddr) string {
  105. return ifAddr.Interface.Name
  106. },
  107. }
  108. }