@@ -2,20 +2,72 @@ package nettools
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"os/exec"
6
7
"runtime"
8
+ "strings"
7
9
)
8
10
9
11
func HasIPv6PingCommand () bool {
12
+ if hasPing6Command () {
13
+ return true
14
+ }
15
+ if _ , err := exec .LookPath ("ping" ); err == nil {
16
+ return true
17
+ }
18
+ return runtime .GOOS == "windows"
19
+ }
20
+
21
+ func hasPing6Command () bool {
10
22
_ , err := exec .LookPath ("ping6" )
11
- return err == nil || runtime . GOOS == "windows"
23
+ return err == nil
12
24
}
13
25
14
26
func Ping (ctx context.Context , address string ) error {
15
- pingCommand := exec .CommandContext (ctx , "ping6" , "-c" , "1" , address )
27
+ cmd := []string {"ping6" , "-c" , "1" , address }
28
+ if ! hasPing6Command () {
29
+ cmd = []string {"ping" , "-6" , "-c" , "1" , address }
30
+ }
16
31
if runtime .GOOS == "windows" {
17
- pingCommand = exec . CommandContext ( ctx , "ping" , "/n" , "1" , address )
32
+ cmd = [] string { "ping" , "/n" , "1" , address }
18
33
}
19
34
20
- return pingCommand .Run ()
35
+ if out , err := exec .CommandContext (ctx , cmd [0 ], cmd [1 :]... ).Output (); err != nil {
36
+ return pingError (err , cmd , out )
37
+ }
38
+ return nil
39
+ }
40
+
41
+ type PingError struct {
42
+ err error
43
+ cmd []string
44
+ output string
45
+ }
46
+
47
+ func (p PingError ) Err () error {
48
+ return p .err
49
+ }
50
+
51
+ func (p PingError ) Output () string {
52
+ return p .output
53
+ }
54
+
55
+ func (p PingError ) Cmd () string {
56
+ return strings .Join (p .cmd , " " )
57
+ }
58
+
59
+ func (p PingError ) Error () string {
60
+ return fmt .Sprintf ("ping => err: %s, exec: %s, output: %s" , p .err , p .Cmd (), p .output )
61
+ }
62
+
63
+ func pingError (
64
+ err error ,
65
+ cmd []string ,
66
+ output []byte ,
67
+ ) error {
68
+ return PingError {
69
+ err : err ,
70
+ cmd : cmd ,
71
+ output : string (output ),
72
+ }
21
73
}
0 commit comments