Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@kotakanbe
Created September 17, 2015 02:59
Show Gist options
  • Star 70 You must be signed in to star a gist
  • Fork 24 You must be signed in to fork a gist
  • Save kotakanbe/d3059af990252ba89a82 to your computer and use it in GitHub Desktop.
Save kotakanbe/d3059af990252ba89a82 to your computer and use it in GitHub Desktop.
get all IP address from CIDR in golang
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)
}
@michaelwayout
Copy link

Hosts gets panic when using /32 CIDR
https://play.golang.org/p/D9F0qmFbN5B

@adam-hanna
Copy link

@kfelter
Copy link

kfelter commented Jun 7, 2021

Thanks! 👍

@alinz
Copy link

alinz commented Mar 21, 2022

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
}

@andig
Copy link

andig commented Nov 1, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment