package main import ( "errors" "net" "time" "github.com/miekg/dns" probing "github.com/prometheus-community/pro-bing" ) type PingResult struct { RTT time.Duration Alive bool Err error IP string } type PingOptions struct { Timeout time.Duration Size int DisableIPv6 bool DNSServer string } func resolveWithCustomDNS(server, host string) (string, error) { c := new(dns.Client) m := new(dns.Msg) m.SetQuestion(dns.Fqdn(host), dns.TypeA) resp, _, err := c.Exchange(m, server) if err != nil { return "", err } for _, ans := range resp.Answer { if a, ok := ans.(*dns.A); ok { return a.A.String(), nil } } return "", errors.New("no A record found") } func resolveHost(host, dnsServer string, disableIPv6 bool) (string, error) { if ip := net.ParseIP(host); ip != nil { return host, nil } if dnsServer != "" { if _, _, err := net.SplitHostPort(dnsServer); err != nil { dnsServer = net.JoinHostPort(dnsServer, "53") } return resolveWithCustomDNS(dnsServer, host) } if disableIPv6 { ips, err := net.LookupIP(host) if err != nil { return "", err } for _, ip := range ips { if ip.To4() != nil { return ip.String(), nil } } return "", errors.New("no IPv4 address found") } ip, err := net.ResolveIPAddr("ip", host) if err != nil { return "", err } return ip.IP.String(), nil } func doPing(host string, opts PingOptions) PingResult { ip, err := resolveHost(host, opts.DNSServer, opts.DisableIPv6) if err != nil { return PingResult{Alive: false, Err: err} } pinger, err := probing.NewPinger(ip) if err != nil { return PingResult{Alive: false, Err: err, IP: ip} } if opts.DisableIPv6 { pinger.SetNetwork("ip4") } pinger.Count = 1 pinger.Timeout = opts.Timeout pinger.Size = opts.Size // falls du im Container kein CAP_NET_RAW gibst: pinger.SetPrivileged(false) // oder aus Config // wenn du CAP_NET_RAW vergibst: // pinger.SetPrivileged(true) if err := pinger.Run(); err != nil { return PingResult{Alive: false, Err: err, IP: ip} } stats := pinger.Statistics() if stats.PacketsRecv < 1 { return PingResult{Alive: false, Err: errors.New("no reply"), IP: ip} } return PingResult{ RTT: stats.AvgRtt, Alive: true, IP: ip, } }