Python has a method in the ipaddress module to list all the IPs in a network. eg.
import ipaddress
ips = [ip for ip in ipaddress.ip_network('8.8.8.0/24').hosts()]
How would you do the same thing in Go?
Python has a method in the ipaddress module to list all the IPs in a network. eg.
import ipaddress
ips = [ip for ip in ipaddress.ip_network('8.8.8.0/24').hosts()]
How would you do the same thing in Go?
convert the CIDR address and netmask to uint32. Find the start and finish and then loop on the uint32 to get the addresses
package main
import (
"encoding/binary"
"fmt"
"log"
"net"
)
func main() {
// convert string to IPNet struct
_, ipv4Net, err := net.ParseCIDR("192.168.255.128/25")
if err != nil {
log.Fatal(err)
}
// convert IPNet struct mask and address to uint32
// network is BigEndian
mask := binary.BigEndian.Uint32(ipv4Net.Mask)
start := binary.BigEndian.Uint32(ipv4Net.IP)
// find the final address
finish := (start & mask) | (mask ^ 0xffffffff)
// loop through addresses as uint32
for i := start; i <= finish; i++ {
// convert back to net.IP
ip := make(net.IP, 4)
binary.BigEndian.PutUint32(ip, i)
fmt.Println(ip)
}
}
I found a way to do it based on https://play.golang.org/p/fe-F2k6prlA by adam-hanna in this thread - https://gist.github.com/kotakanbe/d3059af990252ba89a82
package main
import (
"fmt"
"log"
"net"
"time"
)
func Hosts(cidr string) ([]string, int, error) {
ip, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, 0, err
}
var ips []string
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
ips = append(ips, ip.String())
}
// remove network address and broadcast address
lenIPs := len(ips)
switch {
case lenIPs < 2:
return ips, lenIPs, nil
default:
return ips[1 : len(ips)-1], lenIPs - 2, nil
}
}
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
func main() {
ips, count, err := Hosts("8.8.8.0/24")
if err != nil {
log.Fatal(err)
}
for n := 0; n <= count; n += 8 {
fmt.Println(ips[n])
}
}
Here is the equivalent using the IPAddress Go module. Disclaimer: I am the project manager.
import a "github.com/seancfoley/ipaddress-go/ipaddr"
var addrs []*a.IPAddress
block := a.NewIPAddressString("8.8.8.0/24").GetAddress()
for i := block.Iterator(); i.HasNext(); {
addrs = append(addrs, i.Next())
}
Use append(addrs, iter.Next().GetNetIP()) for a slice of net.IP.