// NewState returns a new State object. func NewState(id string) (state *State) { pinger := fastping.NewPinger() state = &State{ PingSessions: make(map[string]*Session), PingChecker: Checker{ ID: id, PingLimit: DefaultPingLimit, }, Pinger: pinger, } pinger.OnRecv = state.onRecv pinger.RunLoop() return }
func runFastPing(ips []string, src string, timeout int) { p := fastping.NewPinger() p.Network("udp") if len(src) > 0 { p.Source(src) } for _, ip := range ips { p.AddIP(ip) } p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) { fmt.Printf("%s %d\n", addr.String(), rtt.Nanoseconds()/1000000) } p.MaxRTT = time.Duration(timeout) * time.Millisecond err := p.Run() if err != nil { log.Printf("error occur: %v\n", err) } }
func main() { sort.Strings(ips) p := fastping.NewPinger() p.Network("udp") p.MaxRTT = timeout for _, ip := range ips { ra, err := net.ResolveIPAddr("ip4:icmp", ip) if err != nil { fmt.Println(err) os.Exit(1) } p.AddIPAddr(ra) } results := map[string]string{} p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) { results[addr.String()] = fmt.Sprintf("%.0f", rtt.Seconds()*1000) // integer millis } if err := p.Run(); err != nil { fmt.Printf("p.Run failed with: %v", err) } strs := []string{time.Now().UTC().Format(time.RFC3339)} for _, ip := range ips { strs = append(strs, ip) if v, exists := results[ip]; exists { strs = append(strs, fmt.Sprintf("%-7.7s", v)) } else { strs = append(strs, "timeout") } } fmt.Printf(strings.Join(strs, ", ") + "\n") }
func pingHost(host string) { p := fastping.NewPinger() tags := opentsdb.TagSet{"dst_host": host} resolved := 0 defer func() { collect.Put("ping.resolved", tags, resolved) }() ra, err := net.ResolveIPAddr("ip4:icmp", host) if err != nil { return } resolved = 1 p.AddIPAddr(ra) p.MaxRTT = time.Second * 5 timeout := 1 p.OnRecv = func(addr *net.IPAddr, t time.Duration) { collect.Put("ping.rtt", tags, float64(t)/float64(time.Millisecond)) timeout = 0 } if err := p.Run(); err != nil { slog.Errorln(err) } collect.Put("ping.timeout", tags, timeout) }
func main() { // Uncomment the following lines if you need to time the options parsing //log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) //log.Println(": Program started") // Configure Command Line Options var useUDP, quiet, debug bool var maxRTT time.Duration var numPing int getopt.BoolVarLong(&useUDP, "udp", 'u', "use UDP instead of ICMP") getopt.BoolVarLong(&quiet, "quiet", 'q', "only display host data") getopt.BoolVarLong(&debug, "debug", 'v', "print additional messages") maxRTT = defaultMaxRTT getopt.DurationVarLong(&maxRTT, "rtt", 't', "max RTT for each ping") numPing = defaultPingCount getopt.IntVarLong(&numPing, "count", 'n', "max number of pings per target") getopt.SetParameters("startIP endIP") getopt.Parse() // Verify arguments if getopt.NArgs() != 2 { log.Println("Incorrect number of arguments!") getopt.PrintUsage(os.Stderr) os.Exit(1) } startIPString := getopt.Arg(0) endIPString := getopt.Arg(1) // Test for incompatible options if quiet && debug { log.Println("`quiet` and `debug` are incompatible") getopt.PrintUsage(os.Stderr) os.Exit(1) } if debug { log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) log.Println(": Command Line Parsing complete") } // Convert to IP object startIP := net.ParseIP(startIPString) if startIP == nil { log.Fatal("Start IP,", startIPString, ", is not a valid IP address") } if debug { log.Println(": Start IP\t", startIPString) } endIP := net.ParseIP(endIPString) if endIP == nil { log.Fatal("End IP,", endIPString, ", is not a valid IP address") } if debug { log.Println(": End IP \t", endIPString) } netProto := "ip4:icmp" if strings.Index(startIPString, ":") != -1 { netProto = "ip6:ipv6-icmp" } p := fastping.NewPinger() p.MaxRTT = maxRTT p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) { var device resultData device.PingResult = addr.String() + "\t" + roundDuration(baseRTT+rtt, time.Millisecond).String() ips = append(ips, device) p.RemoveIPAddr(addr) } currentIP := make(net.IP, len(startIP)) for copy(currentIP, startIP); bytes.Compare(currentIP, endIP) <= 0; inc(currentIP) { ra, err := net.ResolveIPAddr(netProto, currentIP.String()) if err != nil { log.Fatal(err) } p.AddIPAddr(ra) } if useUDP { p.Network("udp") } if debug { log.Println(": Start Scan") } for index := 0; index < numPing; index++ { baseRTT = time.Duration(index) * maxRTT err := p.Run() if err != nil { log.Fatal("Pinger returns error: ", err) } } if debug { log.Println(": Scan complete") } if !quiet { fmt.Println() fmt.Printf("%d devices found\n", len(ips)) fmt.Println() } if debug { log.Println(": Start Host Lookup") } // Query DNS for the name of each device found by the ping scan var ipAndTime []string var hostname string var wg sync.WaitGroup for index, ip := range ips { ipAndTime = strings.SplitN(ip.PingResult, "\t", 2) wg.Add(1) go func(ipString string, localIndex int) { hosts, err := net.LookupAddr(ipString) if err != nil { hostname = "Error: " + err.Error() } else { hostname = strings.Join(hosts, ", ") } ips[localIndex].HostResult = hostname wg.Done() }(ipAndTime[0], index) } wg.Wait() if debug { log.Println(": DNS complete") } sort.Sort(byIP(ips)) if debug { log.Println(": Sort complete") } for _, ip := range ips { fmt.Printf("%-25s\t--> %s\n", ip.PingResult, ip.HostResult) } if !quiet { fmt.Println() } if debug { log.Println(": Program complete") } }