Created
December 7, 2020 12:05
-
-
Save unakatsuo/dd1b7c47cb6db45d423635b291e91556 to your computer and use it in GitHub Desktop.
IP range iteration utility for golang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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