File: randaddr.go

package info (click to toggle)
snowflake 2.10.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,104 kB
  • sloc: makefile: 5
file content (41 lines) | stat: -rw-r--r-- 1,090 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package main

import (
	"crypto/rand"
	"fmt"
	"net"
)

// randIPAddr generates a random IP address within the network represented by
// ipnet.
func randIPAddr(ipnet *net.IPNet) (net.IP, error) {
	if len(ipnet.IP) != len(ipnet.Mask) {
		return nil, fmt.Errorf("IP and mask have unequal lengths (%v and %v)", len(ipnet.IP), len(ipnet.Mask))
	}
	ip := make(net.IP, len(ipnet.IP))
	_, err := rand.Read(ip)
	if err != nil {
		return nil, err
	}
	for i := 0; i < len(ipnet.IP); i++ {
		ip[i] = (ipnet.IP[i] & ipnet.Mask[i]) | (ip[i] & ^ipnet.Mask[i])
	}
	return ip, nil
}

// parseIPCIDR parses a CIDR-notation IP address and prefix length; or if that
// fails, as a plain IP address (with the prefix length equal to the address
// length).
func parseIPCIDR(s string) (*net.IPNet, error) {
	_, ipnet, err := net.ParseCIDR(s)
	if err == nil {
		return ipnet, nil
	}
	// IP/mask failed; try just IP now, but remember err, to return it in
	// case that fails too.
	ip := net.ParseIP(s)
	if ip != nil {
		return &net.IPNet{IP: ip, Mask: net.CIDRMask(len(ip)*8, len(ip)*8)}, nil
	}
	return nil, err
}