如何列出网络中的所有IP
How to list all IPs in a network
Python 在 ipaddress
模块中有一个方法可以列出网络中的所有 IP。例如
import ipaddress
ips = [ip for ip in ipaddress.ip_network('8.8.8.0/24').hosts()]
你会如何在 Go 中做同样的事情?
您可以使用net.ParseCIDR为相应的网络生成一个*IPNet。
我找到了一种基于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])
}
}
将 CIDR 地址和网络掩码转换为 uint32。找到开始和结束,然后在 uint32 上循环以获取地址
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)
}
}
Python 在 ipaddress
模块中有一个方法可以列出网络中的所有 IP。例如
import ipaddress
ips = [ip for ip in ipaddress.ip_network('8.8.8.0/24').hosts()]
你会如何在 Go 中做同样的事情?
您可以使用net.ParseCIDR为相应的网络生成一个*IPNet。
我找到了一种基于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])
}
}
将 CIDR 地址和网络掩码转换为 uint32。找到开始和结束,然后在 uint32 上循环以获取地址
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)
}
}