func (p *Pinger) SetPrivileged(privileged bool) {
	if privileged {
		p.network = "ip"
	} else {
		p.network = "udp"
	}
}
SetPrivileged sets the type of ping pinger will send.
false means pinger will send an "unprivileged" UDP ping.
true means pinger will send a "privileged" raw ICMP ping.
NOTE: setting to true requires that it be run with super-user privileges.
package main
import (
	"bytes"
	"database/sql"
	"encoding/binary"
	"fmt"
	"log"
	"math"
	"math/rand"
	"net"
	"sync"
	"syscall"
	"time"
	"golang.org/x/net/icmp"
	"golang.org/x/net/ipv4"
	"golang.org/x/net/ipv6"
)
const (
	szLen            = 8
	tsLen            = 8
	protocolICMP     = 1
	protocolIPv6ICMP = 58
)
var (
	ipv4Proto = map[string]string{"ip": "ip4:icmp", "udp": "udp4"}
	ipv6Proto = map[string]string{"ip": "ip6:ipv6-icmp", "udp": "udp6"}
	pingers   map[string]*Pinger
)
type in_flight struct {
	timer   *time.Timer
	pinger  *Pinger
	results chan *Result
	Result
}
type Pinger struct {
	Host string
	Interval time.Duration
	Timeout time.Duration
	Size int
	done chan bool
	conn_ipv4 *icmp.PacketConn
	done_ipv4 chan bool
	conn_ipv6 *icmp.PacketConn
	done_ipv6 chan bool
	recv      chan *packet
	size     int
	id       int
	sequence int
	network  string
	wg       sync.WaitGroup
	pending map[int]in_flight  
	results chan *Result
}
func NewPinger(host string, interval time.Duration, results chan *Result) (*Pinger, error) {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	return &Pinger{
		Host:      host,
		Interval:  interval,
		Timeout:   5 * time.Second,
		id:        r.Intn(math.MaxInt16),
		network:   "udp",
		Size:      128,
		done:      make(chan bool),
		done_ipv4: make(chan bool),
		done_ipv6: make(chan bool),
		pending:   make(map[int]in_flight, 1),
		results:   results,
	}, nil
}
type packet struct {
	ipv4   bool
	bytes  []byte
	nbytes int
	ttl    int
}
type Result = struct {
	TS   time.Time
	Host string
	IP   string
	Rtt  time.Duration
}