1
0
mirror of https://github.com/taigrr/go-fastping synced 2025-01-18 05:03:15 -08:00
go-fastping/cmd/ping/ping.go

100 lines
1.9 KiB
Go

package main
import (
"flag"
"fmt"
"net"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/tatsushid/go-fastping"
)
type response struct {
addr *net.IPAddr
rtt time.Duration
}
func main() {
var useUDP bool
flag.BoolVar(&useUDP, "udp", false, "use non-privileged datagram-oriented UDP as ICMP endpoints")
flag.BoolVar(&useUDP, "u", false, "use non-privileged datagram-oriented UDP as ICMP endpoints (shorthand)")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage:\n %s [options] hostname\n\nOptions:\n", os.Args[0])
flag.PrintDefaults()
}
flag.Parse()
hostname := flag.Arg(0)
if len(hostname) == 0 {
flag.Usage()
os.Exit(1)
}
p := fastping.NewPinger()
if useUDP {
p.Network("udp")
}
netProto := "ip4:icmp"
if strings.Index(hostname, ":") != -1 {
netProto = "ip6:ipv6-icmp"
}
ra, err := net.ResolveIPAddr(netProto, hostname)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
results := make(map[string]*response)
results[ra.String()] = nil
p.AddIPAddr(ra)
onRecv, onIdle := make(chan *response), make(chan bool)
p.OnRecv = func(addr *net.IPAddr, t time.Duration) {
onRecv <- &response{addr: addr, rtt: t}
}
p.OnIdle = func() {
onIdle <- true
}
p.MaxRTT = time.Second
p.RunLoop()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
signal.Notify(c, syscall.SIGTERM)
loop:
for {
select {
case <-c:
fmt.Println("get interrupted")
break loop
case res := <-onRecv:
if _, ok := results[res.addr.String()]; ok {
results[res.addr.String()] = res
}
case <-onIdle:
for host, r := range results {
if r == nil {
fmt.Printf("%s : unreachable %v\n", host, time.Now())
} else {
fmt.Printf("%s : %v %v\n", host, r.rtt, time.Now())
}
results[host] = nil
}
case <-p.Done():
if err = p.Err(); err != nil {
fmt.Println("Ping failed:", err)
}
break loop
}
}
signal.Stop(c)
p.Stop()
}