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  }