diff --git a/.gitignore b/.gitignore index 5cc6066..0f1e8e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ # Created by .ignore support plugin (hsz.mobi) .gitignore .idea/ +vendor +build diff --git a/main.go b/main.go index fe039ed..e5e0260 100644 --- a/main.go +++ b/main.go @@ -17,11 +17,17 @@ limitations under the License. package main import ( + "fmt" + "os" + "github.com/IrekRomaniuk/snap-plugin-collector-pingscan/pingscan" "github.com/intelsdi-x/snap/control/plugin" - "os" ) func main() { - plugin.Start(pingscan.Meta(), pingscan.New(), os.Args[1],) -} \ No newline at end of file + if os.Geteuid() != 0 { + fmt.Fprintf(os.Stderr, "Plugin must be run as root\n") + os.Exit(1) + } + plugin.Start(pingscan.Meta(), pingscan.New(), os.Args[1]) +} diff --git a/pingscan/scan/scan.go b/pingscan/scan/scan.go index b2e90d5..d1616ec 100644 --- a/pingscan/scan/scan.go +++ b/pingscan/scan/scan.go @@ -1,52 +1,44 @@ package scan + //Based on https://gist.github.com/kotakanbe/d3059af990252ba89a82 import ( - "os/exec" - "github.com/IrekRomaniuk/snap-plugin-collector-pingscan/pingscan/targets" + "fmt" + "net" + "os" + "sync/atomic" + + "time" + + fastping "github.com/tatsushid/go-fastping" ) +// Ping takes a slice of IP addresses and return an int count of those that +// respond to ping. The MaxRTT is set to 4 seconds. func Ping(hosts []string) int { - concurrentMax := 200 - pingChan := make(chan string, concurrentMax) - pongChan := make(chan string, len(hosts)) - doneChan := make(chan []string) - //fmt.Printf("concurrentMax=%d hosts=%d -> %s...%s\n", concurrentMax, len(hosts), hosts[0], hosts[len(hosts) - 1]) - for i := 0; i < concurrentMax; i++ { - go sendingPing(pingChan, pongChan) + p := fastping.NewPinger() + p.MaxRTT = 4 * time.Second + var successCount, failCount uint64 + p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) { + atomic.AddUint64(&successCount, 1) + // fmt.Printf("IP Addr: %s receive, RTT: %v successCount: %v \n", addr.String(), rtt, successCount) } - - go receivePong(len(hosts), pongChan, doneChan) - - for _, ip := range hosts { - pingChan <- ip - //fmt.Println("sent: ", ip) + p.OnIdle = func() { + atomic.AddUint64(&failCount, 1) + // fmt.Println("timed out - finish") } - alives := <-doneChan - result := targets.DeleteEmpty(alives) - //fmt.Printf("\n%d/%d %d\n", len(result),len(hosts),concurrentMax) - return len(result) -} - -func sendingPing(pingChan <-chan string, pongChan chan <- string) { - for ip := range pingChan { - _, err := exec.Command("ping", "-c", "1", "-w", "1", ip).Output() - if err == nil { - pongChan <- ip - //fmt.Printf("%s is alive\n", ip) - } else { - pongChan <- "" - //fmt.Printf("%s is dead\n", ip) + for _, ip := range hosts { + // fmt.Printf("adding ip: %v \n", ip) + err := p.AddIP(ip) + if err != nil { + fmt.Fprintf(os.Stderr, "Error adding IP (%v): %v", ip, err) } } -} -func receivePong(pongNum int, pongChan <-chan string, doneChan chan <- []string) { - var alives []string - for i := 0; i < pongNum; i++ { - ip := <-pongChan - //fmt.Println("received: ", ip) - alives = append(alives, ip) + err := p.Run() + if err != nil { + fmt.Fprintf(os.Stderr, "Error during Ping.Run(): %v", err) } - doneChan <- alives -} \ No newline at end of file + + return int(successCount) +}