ipaddr.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package sockaddr
  2. import (
  3. "fmt"
  4. "math/big"
  5. "net"
  6. "strings"
  7. )
  8. // Constants for the sizes of IPv3, IPv4, and IPv6 address types.
  9. const (
  10. IPv3len = 6
  11. IPv4len = 4
  12. IPv6len = 16
  13. )
  14. // IPAddr is a generic IP address interface for IPv4 and IPv6 addresses,
  15. // networks, and socket endpoints.
  16. type IPAddr interface {
  17. SockAddr
  18. AddressBinString() string
  19. AddressHexString() string
  20. Cmp(SockAddr) int
  21. CmpAddress(SockAddr) int
  22. CmpPort(SockAddr) int
  23. FirstUsable() IPAddr
  24. Host() IPAddr
  25. IPPort() IPPort
  26. LastUsable() IPAddr
  27. Maskbits() int
  28. NetIP() *net.IP
  29. NetIPMask() *net.IPMask
  30. NetIPNet() *net.IPNet
  31. Network() IPAddr
  32. Octets() []int
  33. }
  34. // IPPort is the type for an IP port number for the TCP and UDP IP transports.
  35. type IPPort uint16
  36. // IPPrefixLen is a typed integer representing the prefix length for a given
  37. // IPAddr.
  38. type IPPrefixLen byte
  39. // ipAddrAttrMap is a map of the IPAddr type-specific attributes.
  40. var ipAddrAttrMap map[AttrName]func(IPAddr) string
  41. var ipAddrAttrs []AttrName
  42. func init() {
  43. ipAddrInit()
  44. }
  45. // NewIPAddr creates a new IPAddr from a string. Returns nil if the string is
  46. // not an IPv4 or an IPv6 address.
  47. func NewIPAddr(addr string) (IPAddr, error) {
  48. ipv4Addr, err := NewIPv4Addr(addr)
  49. if err == nil {
  50. return ipv4Addr, nil
  51. }
  52. ipv6Addr, err := NewIPv6Addr(addr)
  53. if err == nil {
  54. return ipv6Addr, nil
  55. }
  56. return nil, fmt.Errorf("invalid IPAddr %v", addr)
  57. }
  58. // IPAddrAttr returns a string representation of an attribute for the given
  59. // IPAddr.
  60. func IPAddrAttr(ip IPAddr, selector AttrName) string {
  61. fn, found := ipAddrAttrMap[selector]
  62. if !found {
  63. return ""
  64. }
  65. return fn(ip)
  66. }
  67. // IPAttrs returns a list of attributes supported by the IPAddr type
  68. func IPAttrs() []AttrName {
  69. return ipAddrAttrs
  70. }
  71. // MustIPAddr is a helper method that must return an IPAddr or panic on invalid
  72. // input.
  73. func MustIPAddr(addr string) IPAddr {
  74. ip, err := NewIPAddr(addr)
  75. if err != nil {
  76. panic(fmt.Sprintf("Unable to create an IPAddr from %+q: %v", addr, err))
  77. }
  78. return ip
  79. }
  80. // ipAddrInit is called once at init()
  81. func ipAddrInit() {
  82. // Sorted for human readability
  83. ipAddrAttrs = []AttrName{
  84. "host",
  85. "address",
  86. "port",
  87. "netmask",
  88. "network",
  89. "mask_bits",
  90. "binary",
  91. "hex",
  92. "first_usable",
  93. "last_usable",
  94. "octets",
  95. }
  96. ipAddrAttrMap = map[AttrName]func(ip IPAddr) string{
  97. "address": func(ip IPAddr) string {
  98. return ip.NetIP().String()
  99. },
  100. "binary": func(ip IPAddr) string {
  101. return ip.AddressBinString()
  102. },
  103. "first_usable": func(ip IPAddr) string {
  104. return ip.FirstUsable().String()
  105. },
  106. "hex": func(ip IPAddr) string {
  107. return ip.AddressHexString()
  108. },
  109. "host": func(ip IPAddr) string {
  110. return ip.Host().String()
  111. },
  112. "last_usable": func(ip IPAddr) string {
  113. return ip.LastUsable().String()
  114. },
  115. "mask_bits": func(ip IPAddr) string {
  116. return fmt.Sprintf("%d", ip.Maskbits())
  117. },
  118. "netmask": func(ip IPAddr) string {
  119. switch v := ip.(type) {
  120. case IPv4Addr:
  121. ipv4Mask := IPv4Addr{
  122. Address: IPv4Address(v.Mask),
  123. Mask: IPv4HostMask,
  124. }
  125. return ipv4Mask.String()
  126. case IPv6Addr:
  127. ipv6Mask := new(big.Int)
  128. ipv6Mask.Set(v.Mask)
  129. ipv6MaskAddr := IPv6Addr{
  130. Address: IPv6Address(ipv6Mask),
  131. Mask: ipv6HostMask,
  132. }
  133. return ipv6MaskAddr.String()
  134. default:
  135. return fmt.Sprintf("<unsupported type: %T>", ip)
  136. }
  137. },
  138. "network": func(ip IPAddr) string {
  139. return ip.Network().NetIP().String()
  140. },
  141. "octets": func(ip IPAddr) string {
  142. octets := ip.Octets()
  143. octetStrs := make([]string, 0, len(octets))
  144. for _, octet := range octets {
  145. octetStrs = append(octetStrs, fmt.Sprintf("%d", octet))
  146. }
  147. return strings.Join(octetStrs, " ")
  148. },
  149. "port": func(ip IPAddr) string {
  150. return fmt.Sprintf("%d", ip.IPPort())
  151. },
  152. }
  153. }