Skip to content

Instantly share code, notes, and snippets.

@unakatsuo
Created December 7, 2020 12:05
Show Gist options
  • Save unakatsuo/dd1b7c47cb6db45d423635b291e91556 to your computer and use it in GitHub Desktop.
Save unakatsuo/dd1b7c47cb6db45d423635b291e91556 to your computer and use it in GitHub Desktop.
IP range iteration utility for golang
// IterateIPRange calculates the sequence of IP address from beginAddr to endAddr
// then calls the callback cb for each address of the sequence.
// beginAddr value must be smaller than endAddr.
func IterateIPRange(beginAddr, endAddr net.IP, cb func(addr net.IP)) error {
incIP := func(ip net.IP) net.IP {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
return ip
}
gtIP := func(a, b net.IP) bool {
for i := len(a) - 1; i >= 0; i-- {
if a[i] > b[i] {
return false
}
}
return true
}
if !gtIP(beginAddr, endAddr) {
return fmt.Errorf("beginIP must be smaller than endIP: begin=%s, end=%s", beginAddr, endAddr)
}
var addr = make(net.IP, len(beginAddr))
for copy(addr, beginAddr); gtIP(addr, endAddr); addr = incIP(addr) {
cb(addr)
}
return nil
}
// IterateIPSubnet walks through all the IP addresses in the subnet range.
func IterateIPSubnet(subnet *net.IPNet, cb func(addr net.IP)) {
startAddr := subnet.IP.Mask(subnet.Mask)
endAddr := make(net.IP, len(startAddr))
for i := 0; i <= len(startAddr)-1; i++ {
endAddr[i] = byte(startAddr[i]) | byte(subnet.Mask[i]^0xFF)
}
if err := IterateIPRange(startAddr, endAddr, cb); err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment