7
7
"encoding/binary"
8
8
"errors"
9
9
"fmt"
10
+ "math/rand"
10
11
"net"
11
12
"syscall"
12
13
"time"
@@ -67,13 +68,15 @@ func (this *IcmpPing) ping_rootless(ctx context.Context) IPingResult {
67
68
IcmpCloseHandle (handle )
68
69
}
69
70
}()
71
+ r := rand .New (rand .NewSource (time .Now ().UnixNano ()))
70
72
if isipv6 {
71
73
handle = Icmp6CreateFile ()
72
74
if handle == syscall .InvalidHandle {
73
75
return this .errorResult (errors .New ("IcmpCreateFile failed" ))
74
76
}
75
- data := make ([]byte , 32 )
76
- recv := Icmp6SendEcho (handle , ip , data , this .Timeout )
77
+ data := make ([]byte , this .Size )
78
+ r .Read (data )
79
+ recv := Icmp6SendEcho (handle , ip , data , this .Timeout , this .TTL )
77
80
if recv == nil {
78
81
return this .errorResult (errors .New ("IcmpSendEcho failed" ))
79
82
}
@@ -92,8 +95,9 @@ func (this *IcmpPing) ping_rootless(ctx context.Context) IPingResult {
92
95
if handle == syscall .InvalidHandle {
93
96
return this .errorResult (errors .New ("IcmpCreateFile failed" ))
94
97
}
95
- data := make ([]byte , 32 )
96
- recv := IcmpSendEcho (handle , ip , data , this .Timeout )
98
+ data := make ([]byte , this .Size )
99
+ r .Read (data )
100
+ recv := IcmpSendEcho (handle , ip , data , this .Timeout , this .TTL )
97
101
if recv == nil {
98
102
return this .errorResult (errors .New ("IcmpSendEcho failed" ))
99
103
}
@@ -124,8 +128,14 @@ func IcmpCloseHandle(h syscall.Handle) uintptr {
124
128
return ret
125
129
}
126
130
127
- func IcmpSendEcho (handle syscall.Handle , ip net.IP , data []byte , timeout time.Duration ) []byte {
128
- buf := make ([]byte , 1500 )
131
+ func IcmpSendEcho (handle syscall.Handle , ip net.IP , data []byte , timeout time.Duration , ttl int ) []byte {
132
+ buf := make ([]byte , (int )(unsafe .Sizeof (icmp_echo_reply {}))+ len (data ))
133
+ var pOptions * ip_option_information
134
+ if ttl > 0 {
135
+ pOptions = & ip_option_information {
136
+ ttl : uint8 (ttl ),
137
+ }
138
+ }
129
139
n , _ , _ := icmpSendEcho2 .Call (
130
140
uintptr (handle ), // icmphandle
131
141
0 , // event
@@ -134,7 +144,7 @@ func IcmpSendEcho(handle syscall.Handle, ip net.IP, data []byte, timeout time.Du
134
144
uintptr (ipv4ToInt (ip )), // destinationaddress
135
145
uintptr (unsafe .Pointer (& data [0 ])), // requestdata
136
146
uintptr (len (data )), // requestsize
137
- 0 , // requestoptions
147
+ uintptr ( unsafe . Pointer ( pOptions )), // requestoptions
138
148
uintptr (unsafe .Pointer (& buf [0 ])), // replaybuffer
139
149
uintptr (len (buf )), // replysize
140
150
uintptr (timeout .Milliseconds ()), // timeout
@@ -150,15 +160,21 @@ func Icmp6CreateFile() syscall.Handle {
150
160
return syscall .Handle (h )
151
161
}
152
162
153
- func Icmp6SendEcho (handle syscall.Handle , ip net.IP , data []byte , timeout time.Duration ) []byte {
163
+ func Icmp6SendEcho (handle syscall.Handle , ip net.IP , data []byte , timeout time.Duration , ttl int ) []byte {
154
164
ip6source := syscall.RawSockaddrInet6 {
155
165
Family : syscall .AF_INET6 ,
156
166
}
157
167
ip6dest := syscall.RawSockaddrInet6 {
158
168
Family : syscall .AF_INET6 ,
159
169
}
160
170
copy (ip6dest .Addr [:], ip )
161
- buf := make ([]byte , 1500 )
171
+ buf := make ([]byte , (int )(unsafe .Sizeof (icmpv6_echo_reply {}))+ len (data ))
172
+ var pOptions * ip_option_information
173
+ if ttl > 0 {
174
+ pOptions = & ip_option_information {
175
+ ttl : uint8 (ttl ),
176
+ }
177
+ }
162
178
n , _ , _ := icmp6SendEcho2 .Call (
163
179
uintptr (handle ), // icmphandle
164
180
0 , // event
@@ -168,7 +184,7 @@ func Icmp6SendEcho(handle syscall.Handle, ip net.IP, data []byte, timeout time.D
168
184
uintptr (unsafe .Pointer (& ip6dest )), // destinationaddress
169
185
uintptr (unsafe .Pointer (& data [0 ])), // requestdata
170
186
uintptr (len (data )), // requestsize
171
- 0 , // requestoptions
187
+ uintptr ( unsafe . Pointer ( pOptions )), // requestoptions
172
188
uintptr (unsafe .Pointer (& buf [0 ])), // replaybuffer
173
189
uintptr (len (buf )), // replysize
174
190
uintptr (timeout .Milliseconds ()), // timeout
@@ -187,6 +203,8 @@ func icmpStatusToString(status uint32) string {
187
203
return "destination host was unreachable"
188
204
case 11010 :
189
205
return "request timed out"
206
+ case 11013 :
207
+ return "time exceeded"
190
208
}
191
209
return fmt .Sprintf ("unknown error (%d)" , status )
192
210
}
0 commit comments