github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/util/ip.go (about)

     1  package util
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  )
     7  
     8  // GetIPFromCIDR Naive implementation, but works
     9  func GetIPFromCIDR(cidr string, n int) (net.IP, error) {
    10  	if n < 0 {
    11  		return nil, fmt.Errorf("cannot compute n=%d IP address", n)
    12  	}
    13  	_, ipnet, err := net.ParseCIDR(cidr)
    14  	if err != nil {
    15  		return nil, fmt.Errorf("error parsing CIDR: %v", err)
    16  	}
    17  
    18  	// Need a copy of the IP byte slice to reuse ipnet
    19  	ip := make([]byte, len(ipnet.IP), cap(ipnet.IP))
    20  	copy(ip, ipnet.IP)
    21  
    22  	// Increment the IP address n times
    23  	for j := 0; j < n; j++ {
    24  		for i := len(ip) - 1; i >= 0; i-- {
    25  			ip[i]++
    26  			if ip[i] != 0 {
    27  				break
    28  			}
    29  		}
    30  	}
    31  
    32  	// Verify the resulting IP is contained in the CIDR
    33  	if !ipnet.Contains(ip) {
    34  		return nil, fmt.Errorf("Could not compute the n=%d IP address of CIDR %q (resulting IP %q is not in CIDR)", n, cidr, net.IP(ip))
    35  	}
    36  
    37  	return ip, nil
    38  }