Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: webrtc/base/winping.cc

Issue 2866183004: Deleted unused method EstimateMTU, and the WinPing class. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/winping.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/base/winping.h"
12
13 #include <Iphlpapi.h>
14
15 #include <algorithm>
16
17 #include "webrtc/base/byteorder.h"
18 #include "webrtc/base/checks.h"
19 #include "webrtc/base/ipaddress.h"
20 #include "webrtc/base/logging.h"
21 #include "webrtc/base/nethelpers.h"
22 #include "webrtc/base/socketaddress.h"
23
24 namespace rtc {
25
26 //////////////////////////////////////////////////////////////////////
27 // Found in IPExport.h
28 //////////////////////////////////////////////////////////////////////
29
30 typedef struct icmp_echo_reply {
31 ULONG Address; // Replying address
32 ULONG Status; // Reply IP_STATUS
33 ULONG RoundTripTime; // RTT in milliseconds
34 USHORT DataSize; // Reply data size in bytes
35 USHORT Reserved; // Reserved for system use
36 PVOID Data; // Pointer to the reply data
37 struct ip_option_information Options; // Reply options
38 } ICMP_ECHO_REPLY, * PICMP_ECHO_REPLY;
39
40 typedef struct icmpv6_echo_reply_lh {
41 sockaddr_in6 Address;
42 ULONG Status;
43 unsigned int RoundTripTime;
44 } ICMPV6_ECHO_REPLY, *PICMPV6_ECHO_REPLY;
45
46 //
47 // IP_STATUS codes returned from IP APIs
48 //
49
50 #define IP_STATUS_BASE 11000
51
52 #define IP_SUCCESS 0
53 #define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1)
54 #define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2)
55 #define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3)
56 #define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4)
57 #define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5)
58 #define IP_NO_RESOURCES (IP_STATUS_BASE + 6)
59 #define IP_BAD_OPTION (IP_STATUS_BASE + 7)
60 #define IP_HW_ERROR (IP_STATUS_BASE + 8)
61 #define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9)
62 #define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10)
63 #define IP_BAD_REQ (IP_STATUS_BASE + 11)
64 #define IP_BAD_ROUTE (IP_STATUS_BASE + 12)
65 #define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13)
66 #define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14)
67 #define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15)
68 #define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16)
69 #define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17)
70 #define IP_BAD_DESTINATION (IP_STATUS_BASE + 18)
71
72 #define IP_ADDR_DELETED (IP_STATUS_BASE + 19)
73 #define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20)
74 #define IP_MTU_CHANGE (IP_STATUS_BASE + 21)
75 #define IP_UNLOAD (IP_STATUS_BASE + 22)
76 #define IP_ADDR_ADDED (IP_STATUS_BASE + 23)
77 #define IP_MEDIA_CONNECT (IP_STATUS_BASE + 24)
78 #define IP_MEDIA_DISCONNECT (IP_STATUS_BASE + 25)
79 #define IP_BIND_ADAPTER (IP_STATUS_BASE + 26)
80 #define IP_UNBIND_ADAPTER (IP_STATUS_BASE + 27)
81 #define IP_DEVICE_DOES_NOT_EXIST (IP_STATUS_BASE + 28)
82 #define IP_DUPLICATE_ADDRESS (IP_STATUS_BASE + 29)
83 #define IP_INTERFACE_METRIC_CHANGE (IP_STATUS_BASE + 30)
84 #define IP_RECONFIG_SECFLTR (IP_STATUS_BASE + 31)
85 #define IP_NEGOTIATING_IPSEC (IP_STATUS_BASE + 32)
86 #define IP_INTERFACE_WOL_CAPABILITY_CHANGE (IP_STATUS_BASE + 33)
87 #define IP_DUPLICATE_IPADD (IP_STATUS_BASE + 34)
88
89 #define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50)
90 #define MAX_IP_STATUS IP_GENERAL_FAILURE
91 #define IP_PENDING (IP_STATUS_BASE + 255)
92
93 //
94 // Values used in the IP header Flags field.
95 //
96 #define IP_FLAG_DF 0x2 // Don't fragment this packet.
97
98 //
99 // Supported IP Option Types.
100 //
101 // These types define the options which may be used in the OptionsData field
102 // of the ip_option_information structure. See RFC 791 for a complete
103 // description of each.
104 //
105 #define IP_OPT_EOL 0 // End of list option
106 #define IP_OPT_NOP 1 // No operation
107 #define IP_OPT_SECURITY 0x82 // Security option
108 #define IP_OPT_LSRR 0x83 // Loose source route
109 #define IP_OPT_SSRR 0x89 // Strict source route
110 #define IP_OPT_RR 0x7 // Record route
111 #define IP_OPT_TS 0x44 // Timestamp
112 #define IP_OPT_SID 0x88 // Stream ID (obsolete)
113 #define IP_OPT_ROUTER_ALERT 0x94 // Router Alert Option
114
115 #define MAX_OPT_SIZE 40 // Maximum length of IP options in bytes
116
117 //////////////////////////////////////////////////////////////////////
118 // Global Constants and Types
119 //////////////////////////////////////////////////////////////////////
120
121 const char * const ICMP_DLL_NAME = "Iphlpapi.dll";
122 const char * const ICMP_CREATE_FUNC = "IcmpCreateFile";
123 const char * const ICMP_CLOSE_FUNC = "IcmpCloseHandle";
124 const char * const ICMP_SEND_FUNC = "IcmpSendEcho";
125 const char * const ICMP6_CREATE_FUNC = "Icmp6CreateFile";
126 const char * const ICMP6_SEND_FUNC = "Icmp6SendEcho2";
127
128 inline uint32_t ReplySize(uint32_t data_size, int family) {
129 if (family == AF_INET) {
130 // A ping error message is 8 bytes long, so make sure we allow for at least
131 // 8 bytes of reply data.
132 return sizeof(ICMP_ECHO_REPLY) + std::max<uint32_t>(8, data_size);
133 } else if (family == AF_INET6) {
134 // Per MSDN, Send6IcmpEcho2 needs at least one ICMPV6_ECHO_REPLY,
135 // 8 bytes for ICMP header, _and_ an IO_BLOCK_STATUS (2 pointers),
136 // in addition to the data size.
137 return sizeof(ICMPV6_ECHO_REPLY) + data_size + 8 + (2 * sizeof(DWORD*));
138 } else {
139 return 0;
140 }
141 }
142
143 //////////////////////////////////////////////////////////////////////
144 // WinPing
145 //////////////////////////////////////////////////////////////////////
146
147 WinPing::WinPing()
148 : dll_(0), hping_(INVALID_HANDLE_VALUE), create_(0), close_(0), send_(0),
149 create6_(0), send6_(0), data_(0), dlen_(0), reply_(0),
150 rlen_(0), valid_(false) {
151
152 dll_ = LoadLibraryA(ICMP_DLL_NAME);
153 if (!dll_) {
154 LOG(LERROR) << "LoadLibrary: " << GetLastError();
155 return;
156 }
157
158 create_ = (PIcmpCreateFile) GetProcAddress(dll_, ICMP_CREATE_FUNC);
159 close_ = (PIcmpCloseHandle) GetProcAddress(dll_, ICMP_CLOSE_FUNC);
160 send_ = (PIcmpSendEcho) GetProcAddress(dll_, ICMP_SEND_FUNC);
161 if (!create_ || !close_ || !send_) {
162 LOG(LERROR) << "GetProcAddress(ICMP_*): " << GetLastError();
163 return;
164 }
165 hping_ = create_();
166 if (hping_ == INVALID_HANDLE_VALUE) {
167 LOG(LERROR) << "IcmpCreateFile: " << GetLastError();
168 return;
169 }
170
171 if (HasIPv6Enabled()) {
172 create6_ = (PIcmp6CreateFile) GetProcAddress(dll_, ICMP6_CREATE_FUNC);
173 send6_ = (PIcmp6SendEcho2) GetProcAddress(dll_, ICMP6_SEND_FUNC);
174 if (!create6_ || !send6_) {
175 LOG(LERROR) << "GetProcAddress(ICMP6_*): " << GetLastError();
176 return;
177 }
178 hping6_ = create6_();
179 if (hping6_ == INVALID_HANDLE_VALUE) {
180 LOG(LERROR) << "Icmp6CreateFile: " << GetLastError();
181 }
182 }
183
184 dlen_ = 0;
185 rlen_ = ReplySize(dlen_, AF_INET);
186 data_ = new char[dlen_];
187 reply_ = new char[rlen_];
188
189 valid_ = true;
190 }
191
192 WinPing::~WinPing() {
193 if ((hping_ != INVALID_HANDLE_VALUE) && close_) {
194 if (!close_(hping_))
195 LOG(WARNING) << "IcmpCloseHandle: " << GetLastError();
196 }
197 if ((hping6_ != INVALID_HANDLE_VALUE) && close_) {
198 if (!close_(hping6_)) {
199 LOG(WARNING) << "Icmp6CloseHandle: " << GetLastError();
200 }
201 }
202
203 if (dll_)
204 FreeLibrary(dll_);
205
206 delete[] data_;
207 delete[] reply_;
208 }
209
210 WinPing::PingResult WinPing::Ping(IPAddress ip,
211 uint32_t data_size,
212 uint32_t timeout,
213 uint8_t ttl,
214 bool allow_fragments) {
215 if (data_size == 0 || timeout == 0 || ttl == 0) {
216 LOG(LERROR) << "IcmpSendEcho: data_size/timeout/ttl is 0.";
217 return PING_INVALID_PARAMS;
218 }
219
220 RTC_DCHECK(IsValid());
221
222 IP_OPTION_INFORMATION ipopt;
223 memset(&ipopt, 0, sizeof(ipopt));
224 if (!allow_fragments)
225 ipopt.Flags |= IP_FLAG_DF;
226 ipopt.Ttl = ttl;
227
228 uint32_t reply_size = ReplySize(data_size, ip.family());
229
230 if (data_size > dlen_) {
231 delete [] data_;
232 dlen_ = data_size;
233 data_ = new char[dlen_];
234 memset(data_, 'z', dlen_);
235 }
236
237 if (reply_size > rlen_) {
238 delete [] reply_;
239 rlen_ = reply_size;
240 reply_ = new char[rlen_];
241 }
242 DWORD result = 0;
243 if (ip.family() == AF_INET) {
244 result = send_(hping_, ip.ipv4_address().S_un.S_addr, data_,
245 uint16_t(data_size), &ipopt, reply_, reply_size, timeout);
246 } else if (ip.family() == AF_INET6) {
247 sockaddr_in6 src = {0};
248 sockaddr_in6 dst = {0};
249 src.sin6_family = AF_INET6;
250 dst.sin6_family = AF_INET6;
251 dst.sin6_addr = ip.ipv6_address();
252 result = send6_(hping6_, nullptr, nullptr, nullptr, &src, &dst, data_,
253 int16_t(data_size), &ipopt, reply_, reply_size, timeout);
254 }
255 if (result == 0) {
256 DWORD error = GetLastError();
257 if (error == IP_PACKET_TOO_BIG)
258 return PING_TOO_LARGE;
259 if (error == IP_REQ_TIMED_OUT)
260 return PING_TIMEOUT;
261 LOG(LERROR) << "IcmpSendEcho(" << ip.ToSensitiveString()
262 << ", " << data_size << "): " << error;
263 return PING_FAIL;
264 }
265
266 return PING_SUCCESS;
267 }
268
269 //////////////////////////////////////////////////////////////////////
270 // Microsoft Documenation
271 //////////////////////////////////////////////////////////////////////
272 //
273 // Routine Name:
274 //
275 // IcmpCreateFile
276 //
277 // Routine Description:
278 //
279 // Opens a handle on which ICMP Echo Requests can be issued.
280 //
281 // Arguments:
282 //
283 // None.
284 //
285 // Return Value:
286 //
287 // An open file handle or INVALID_HANDLE_VALUE. Extended error information
288 // is available by calling GetLastError().
289 //
290 //////////////////////////////////////////////////////////////////////
291 //
292 // Routine Name:
293 //
294 // IcmpCloseHandle
295 //
296 // Routine Description:
297 //
298 // Closes a handle opened by ICMPOpenFile.
299 //
300 // Arguments:
301 //
302 // IcmpHandle - The handle to close.
303 //
304 // Return Value:
305 //
306 // TRUE if the handle was closed successfully, otherwise FALSE. Extended
307 // error information is available by calling GetLastError().
308 //
309 //////////////////////////////////////////////////////////////////////
310 //
311 // Routine Name:
312 //
313 // IcmpSendEcho
314 //
315 // Routine Description:
316 //
317 // Sends an ICMP Echo request and returns any replies. The
318 // call returns when the timeout has expired or the reply buffer
319 // is filled.
320 //
321 // Arguments:
322 //
323 // IcmpHandle - An open handle returned by ICMPCreateFile.
324 //
325 // DestinationAddress - The destination of the echo request.
326 //
327 // RequestData - A buffer containing the data to send in the
328 // request.
329 //
330 // RequestSize - The number of bytes in the request data buffer.
331 //
332 // RequestOptions - Pointer to the IP header options for the request.
333 // May be null.
334 //
335 // ReplyBuffer - A buffer to hold any replies to the request.
336 // On return, the buffer will contain an array of
337 // ICMP_ECHO_REPLY structures followed by the
338 // options and data for the replies. The buffer
339 // should be large enough to hold at least one
340 // ICMP_ECHO_REPLY structure plus
341 // MAX(RequestSize, 8) bytes of data since an ICMP
342 // error message contains 8 bytes of data.
343 //
344 // ReplySize - The size in bytes of the reply buffer.
345 //
346 // Timeout - The time in milliseconds to wait for replies.
347 //
348 // Return Value:
349 //
350 // Returns the number of ICMP_ECHO_REPLY structures stored in ReplyBuffer.
351 // The status of each reply is contained in the structure. If the return
352 // value is zero, extended error information is available via
353 // GetLastError().
354 //
355 //////////////////////////////////////////////////////////////////////
356
357 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/winping.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698