Example #1
0
// 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
}
Example #2
0
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)
	}
}
Example #3
0
File: pinger.go Project: skypies/pi
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")
}
Example #4
0
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)
}
Example #5
0
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")
	}
}