github.com/netdata/go.d.plugin@v0.58.1/pkg/iprange/range.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package iprange 4 5 import ( 6 "bytes" 7 "fmt" 8 "math/big" 9 "net" 10 ) 11 12 // Family represents IP Range address-family. 13 type Family uint8 14 15 const ( 16 // V4Family is IPv4 address-family. 17 V4Family Family = iota 18 // V6Family is IPv6 address-family. 19 V6Family 20 ) 21 22 // Range represents an IP range. 23 type Range interface { 24 Family() Family 25 Contains(ip net.IP) bool 26 Size() *big.Int 27 fmt.Stringer 28 } 29 30 // New returns new IP Range. 31 // If it is not a valid range (start and end IPs have different address-families, or start > end), 32 // New returns nil. 33 func New(start, end net.IP) Range { 34 if isV4RangeValid(start, end) { 35 return v4Range{start: start, end: end} 36 } 37 if isV6RangeValid(start, end) { 38 return v6Range{start: start, end: end} 39 } 40 return nil 41 } 42 43 type v4Range struct { 44 start net.IP 45 end net.IP 46 } 47 48 // String returns the string form of the range. 49 func (r v4Range) String() string { 50 return fmt.Sprintf("%s-%s", r.start, r.end) 51 } 52 53 // Family returns the range address family. 54 func (r v4Range) Family() Family { 55 return V4Family 56 } 57 58 // Contains reports whether the range includes IP. 59 func (r v4Range) Contains(ip net.IP) bool { 60 return bytes.Compare(ip, r.start) >= 0 && bytes.Compare(ip, r.end) <= 0 61 } 62 63 // Size reports the number of IP addresses in the range. 64 func (r v4Range) Size() *big.Int { 65 return big.NewInt(v4ToInt(r.end) - v4ToInt(r.start) + 1) 66 } 67 68 type v6Range struct { 69 start net.IP 70 end net.IP 71 } 72 73 // String returns the string form of the range. 74 func (r v6Range) String() string { 75 return fmt.Sprintf("%s-%s", r.start, r.end) 76 } 77 78 // Family returns the range address family. 79 func (r v6Range) Family() Family { 80 return V6Family 81 } 82 83 // Contains reports whether the range includes IP. 84 func (r v6Range) Contains(ip net.IP) bool { 85 return bytes.Compare(ip, r.start) >= 0 && bytes.Compare(ip, r.end) <= 0 86 } 87 88 // Size reports the number of IP addresses in the range. 89 func (r v6Range) Size() *big.Int { 90 size := big.NewInt(0) 91 size.Add(size, big.NewInt(0).SetBytes(r.end)) 92 size.Sub(size, big.NewInt(0).SetBytes(r.start)) 93 size.Add(size, big.NewInt(1)) 94 return size 95 } 96 97 func v4ToInt(ip net.IP) int64 { 98 ip = ip.To4() 99 return int64(ip[0])<<24 | int64(ip[1])<<16 | int64(ip[2])<<8 | int64(ip[3]) 100 }