Dwi Siswanto 87ed0b2bb9
build: bump all direct modules (#6290)
* chore: fix non-constant fmt string in call

Signed-off-by: Dwi Siswanto <git@dw1.io>

* build: bump all direct modules

Signed-off-by: Dwi Siswanto <git@dw1.io>

* chore(hosterrorscache): update import path

Signed-off-by: Dwi Siswanto <git@dw1.io>

* fix(charts): break changes

Signed-off-by: Dwi Siswanto <git@dw1.io>

* build: pinned `github.com/zmap/zcrypto` to v0.0.0-20240512203510-0fef58d9a9db

Signed-off-by: Dwi Siswanto <git@dw1.io>

* chore: golangci-lint auto fixes

Signed-off-by: Dwi Siswanto <git@dw1.io>

* chore: satisfy lints

Signed-off-by: Dwi Siswanto <git@dw1.io>

* build: migrate `github.com/xanzy/go-gitlab` => `gitlab.com/gitlab-org/api/client-go`

Signed-off-by: Dwi Siswanto <git@dw1.io>

* feat(json): update build constraints

Signed-off-by: Dwi Siswanto <git@dw1.io>

* chore: dont panicking on close err

Signed-off-by: Dwi Siswanto <git@dw1.io>

---------

Signed-off-by: Dwi Siswanto <git@dw1.io>
2025-07-01 00:40:44 +07:00

89 lines
1.5 KiB
Go

package randomip
import (
"crypto/rand"
"net"
"github.com/pkg/errors"
iputil "github.com/projectdiscovery/utils/ip"
randutil "github.com/projectdiscovery/utils/rand"
)
const (
maxIterations = 255
)
func GetRandomIPWithCidr(cidrs ...string) (net.IP, error) {
if len(cidrs) == 0 {
return nil, errors.Errorf("must specify at least one cidr")
}
randIdx, err := randutil.IntN(len(cidrs))
if err != nil {
return nil, err
}
cidr := cidrs[randIdx]
if !iputil.IsCIDR(cidr) {
return nil, errors.Errorf("%s is not a valid cidr", cidr)
}
baseIp, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}
switch {
case ipnet.Mask[len(ipnet.Mask)-1] == 255:
return baseIp, nil
case iputil.IsIPv4(baseIp.String()):
return getRandomIP(ipnet, 4), nil
case iputil.IsIPv6(baseIp.String()):
return getRandomIP(ipnet, 16), nil
default:
return nil, errors.New("invalid base ip")
}
}
func getRandomIP(ipnet *net.IPNet, size int) net.IP {
ip := ipnet.IP
var iteration int
for iteration < maxIterations {
iteration++
ones, _ := ipnet.Mask.Size()
quotient := ones / 8
remainder := ones % 8
var r []byte
switch size {
case 4, 16:
r = make([]byte, size)
default:
return ip
}
_, err := rand.Read(r)
if err != nil {
break
}
for i := 0; i <= quotient; i++ {
if i == quotient {
shifted := byte(r[i]) >> remainder
r[i] = ipnet.IP[i] + (^ipnet.IP[i] & shifted)
} else {
r[i] = ipnet.IP[i]
}
}
ip = r
if !ip.Equal(ipnet.IP) {
break
}
}
return ip
}