mirror of
https://github.com/taigrr/go-fastping
synced 2025-01-18 05:03:15 -08:00
Option to specify source ip for ping
This commit is contained in:
parent
5bf6f7ec59
commit
a06009512e
@ -23,7 +23,7 @@ func main() {
|
|||||||
flag.BoolVar(&useUDP, "udp", false, "use non-privileged datagram-oriented UDP as ICMP endpoints")
|
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.BoolVar(&useUDP, "u", false, "use non-privileged datagram-oriented UDP as ICMP endpoints (shorthand)")
|
||||||
flag.Usage = func() {
|
flag.Usage = func() {
|
||||||
fmt.Fprintf(os.Stderr, "Usage:\n %s [options] hostname\n\nOptions:\n", os.Args[0])
|
fmt.Fprintf(os.Stderr, "Usage:\n %s [options] hostname [source]\n\nOptions:\n", os.Args[0])
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
}
|
}
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
@ -34,6 +34,11 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
source := ""
|
||||||
|
if flag.NArg() > 1 {
|
||||||
|
source = flag.Arg(1)
|
||||||
|
}
|
||||||
|
|
||||||
p := fastping.NewPinger()
|
p := fastping.NewPinger()
|
||||||
if useUDP {
|
if useUDP {
|
||||||
p.Network("udp")
|
p.Network("udp")
|
||||||
@ -49,6 +54,10 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if source != "" {
|
||||||
|
p.Source(source)
|
||||||
|
}
|
||||||
|
|
||||||
results := make(map[string]*response)
|
results := make(map[string]*response)
|
||||||
results[ra.String()] = nil
|
results[ra.String()] = nil
|
||||||
p.AddIPAddr(ra)
|
p.AddIPAddr(ra)
|
||||||
|
33
fastping.go
33
fastping.go
@ -130,6 +130,7 @@ type Pinger struct {
|
|||||||
// key string is IPAddr.String()
|
// key string is IPAddr.String()
|
||||||
addrs map[string]*net.IPAddr
|
addrs map[string]*net.IPAddr
|
||||||
network string
|
network string
|
||||||
|
source string
|
||||||
hasIPv4 bool
|
hasIPv4 bool
|
||||||
hasIPv6 bool
|
hasIPv6 bool
|
||||||
ctx *context
|
ctx *context
|
||||||
@ -158,6 +159,7 @@ func NewPinger() *Pinger {
|
|||||||
seq: rand.Intn(0xffff),
|
seq: rand.Intn(0xffff),
|
||||||
addrs: make(map[string]*net.IPAddr),
|
addrs: make(map[string]*net.IPAddr),
|
||||||
network: "ip",
|
network: "ip",
|
||||||
|
source: "",
|
||||||
hasIPv4: false,
|
hasIPv4: false,
|
||||||
hasIPv6: false,
|
hasIPv6: false,
|
||||||
Size: TimeSliceLength,
|
Size: TimeSliceLength,
|
||||||
@ -185,6 +187,29 @@ func (p *Pinger) Network(network string) (string, error) {
|
|||||||
return origNet, nil
|
return origNet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Source sets source IP for sending ICMP packets and returns the previous
|
||||||
|
// setting. Empty value indicates to use system default one.
|
||||||
|
func (p *Pinger) Source(source string) (string, error) {
|
||||||
|
origSource := p.source
|
||||||
|
if "" == source {
|
||||||
|
p.mu.Lock()
|
||||||
|
p.source = source
|
||||||
|
p.mu.Unlock()
|
||||||
|
return origSource, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := net.ParseIP(source)
|
||||||
|
if addr == nil {
|
||||||
|
return origSource, errors.New(source + " is not a valid textual representation of an IP address")
|
||||||
|
}
|
||||||
|
|
||||||
|
p.mu.Lock()
|
||||||
|
p.source = source
|
||||||
|
p.mu.Unlock()
|
||||||
|
|
||||||
|
return origSource, nil
|
||||||
|
}
|
||||||
|
|
||||||
// AddIP adds an IP address to Pinger. ipaddr arg should be a string like
|
// AddIP adds an IP address to Pinger. ipaddr arg should be a string like
|
||||||
// "192.0.2.1".
|
// "192.0.2.1".
|
||||||
func (p *Pinger) AddIP(ipaddr string) error {
|
func (p *Pinger) AddIP(ipaddr string) error {
|
||||||
@ -347,8 +372,8 @@ func (p *Pinger) Err() error {
|
|||||||
return p.ctx.err
|
return p.ctx.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pinger) listen(netProto string) *icmp.PacketConn {
|
func (p *Pinger) listen(netProto string, source string) *icmp.PacketConn {
|
||||||
conn, err := icmp.ListenPacket(netProto, "")
|
conn, err := icmp.ListenPacket(netProto, source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
p.ctx.err = err
|
p.ctx.err = err
|
||||||
@ -364,14 +389,14 @@ func (p *Pinger) run(once bool) {
|
|||||||
p.debugln("Run(): Start")
|
p.debugln("Run(): Start")
|
||||||
var conn, conn6 *icmp.PacketConn
|
var conn, conn6 *icmp.PacketConn
|
||||||
if p.hasIPv4 {
|
if p.hasIPv4 {
|
||||||
if conn = p.listen(ipv4Proto[p.network]); conn == nil {
|
if conn = p.listen(ipv4Proto[p.network], p.source); conn == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.hasIPv6 {
|
if p.hasIPv6 {
|
||||||
if conn6 = p.listen(ipv6Proto[p.network]); conn6 == nil {
|
if conn6 = p.listen(ipv6Proto[p.network], p.source); conn6 == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer conn6.Close()
|
defer conn6.Close()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user