Created
September 17, 2015 02:59
-
-
Save kotakanbe/d3059af990252ba89a82 to your computer and use it in GitHub Desktop.
get all IP address from CIDR in 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
package main | |
import ( | |
"net" | |
"os/exec" | |
"github.com/k0kubun/pp" | |
) | |
func Hosts(cidr string) ([]string, error) { | |
ip, ipnet, err := net.ParseCIDR(cidr) | |
if err != nil { | |
return nil, 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 | |
return ips[1 : len(ips)-1], nil | |
} | |
// http://play.golang.org/p/m8TNTtygK0 | |
func inc(ip net.IP) { | |
for j := len(ip) - 1; j >= 0; j-- { | |
ip[j]++ | |
if ip[j] > 0 { | |
break | |
} | |
} | |
} | |
type Pong struct { | |
Ip string | |
Alive bool | |
} | |
func ping(pingChan <-chan string, pongChan chan<- Pong) { | |
for ip := range pingChan { | |
_, err := exec.Command("ping", "-c1", "-t1", ip).Output() | |
var alive bool | |
if err != nil { | |
alive = false | |
} else { | |
alive = true | |
} | |
pongChan <- Pong{Ip: ip, Alive: alive} | |
} | |
} | |
func receivePong(pongNum int, pongChan <-chan Pong, doneChan chan<- []Pong) { | |
var alives []Pong | |
for i := 0; i < pongNum; i++ { | |
pong := <-pongChan | |
// fmt.Println("received:", pong) | |
if pong.Alive { | |
alives = append(alives, pong) | |
} | |
} | |
doneChan <- alives | |
} | |
func main() { | |
hosts, _ := Hosts("192.168.11.0/24") | |
concurrentMax := 100 | |
pingChan := make(chan string, concurrentMax) | |
pongChan := make(chan Pong, len(hosts)) | |
doneChan := make(chan []Pong) | |
for i := 0; i < concurrentMax; i++ { | |
go ping(pingChan, pongChan) | |
} | |
go receivePong(len(hosts), pongChan, doneChan) | |
for _, ip := range hosts { | |
pingChan <- ip | |
// fmt.Println("sent: " + ip) | |
} | |
alives := <-doneChan | |
pp.Println(alives) | |
} |
Thanks! 👍
This is the new version of Host
using new package netip in Go 1.18+
package main
import (
"net/netip"
)
func Hosts(cidr string) ([]netip.Addr, error) {
prefix, err := netip.ParsePrefix(cidr)
if err != nil {
panic(err)
}
var ips []netip.Addr
for addr := prefix.Addr(); prefix.Contains(addr); addr = addr.Next() {
ips = append(ips, addr)
}
if len(ips) < 2 {
return ips, nil
}
return ips[1 : len(ips)-1], nil
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hosts gets panic when using /32 CIDR
https://play.golang.org/p/D9F0qmFbN5B