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 #ifndef WEBRTC_BASE_WINPING_H__
12 #define WEBRTC_BASE_WINPING_H__
13 
14 #if defined(WEBRTC_WIN)
15 
16 #include "webrtc/base/win32.h"
17 #include "webrtc/base/basictypes.h"
18 #include "webrtc/base/IPAddress.h"
19 
20 namespace rtc {
21 
22 // This class wraps a Win32 API for doing ICMP pinging.  This API, unlike the
23 // the normal socket APIs (as implemented on Win9x), will return an error if
24 // an ICMP packet with the dont-fragment bit set is too large.  This means this
25 // class can be used to detect the MTU to a given address.
26 
27 typedef struct ip_option_information {
28     UCHAR   Ttl;                // Time To Live
29     UCHAR   Tos;                // Type Of Service
30     UCHAR   Flags;              // IP header flags
31     UCHAR   OptionsSize;        // Size in bytes of options data
32     PUCHAR  OptionsData;        // Pointer to options data
33 } IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
34 
35 typedef HANDLE (WINAPI *PIcmpCreateFile)();
36 
37 typedef BOOL (WINAPI *PIcmpCloseHandle)(HANDLE icmp_handle);
38 
39 typedef HANDLE (WINAPI *PIcmp6CreateFile)();
40 
41 typedef BOOL (WINAPI *PIcmp6CloseHandle)(HANDLE icmp_handle);
42 
43 typedef DWORD (WINAPI *PIcmpSendEcho)(
44     HANDLE                   IcmpHandle,
45     ULONG                    DestinationAddress,
46     LPVOID                   RequestData,
47     WORD                     RequestSize,
48     PIP_OPTION_INFORMATION   RequestOptions,
49     LPVOID                   ReplyBuffer,
50     DWORD                    ReplySize,
51     DWORD                    Timeout);
52 
53 typedef DWORD (WINAPI *PIcmp6SendEcho2)(
54     HANDLE IcmpHandle,
55     HANDLE Event,
56     FARPROC ApcRoutine,
57     PVOID ApcContext,
58     struct sockaddr_in6 *SourceAddress,
59     struct sockaddr_in6 *DestinationAddress,
60     LPVOID RequestData,
61     WORD RequestSize,
62     PIP_OPTION_INFORMATION RequestOptions,
63     LPVOID ReplyBuffer,
64     DWORD ReplySize,
65     DWORD Timeout
66 );
67 
68 class WinPing {
69 public:
70     WinPing();
71     ~WinPing();
72 
73     // Determines whether the class was initialized correctly.
IsValid()74     bool IsValid() { return valid_; }
75 
76     // Attempts to send a ping with the given parameters.
77     enum PingResult { PING_FAIL, PING_INVALID_PARAMS,
78                       PING_TOO_LARGE, PING_TIMEOUT, PING_SUCCESS };
79     PingResult Ping(IPAddress ip,
80                     uint32_t data_size,
81                     uint32_t timeout_millis,
82                     uint8_t ttl,
83                     bool allow_fragments);
84 
85 private:
86     HMODULE dll_;
87     HANDLE hping_;
88     HANDLE hping6_;
89     PIcmpCreateFile create_;
90     PIcmpCloseHandle close_;
91     PIcmpSendEcho send_;
92     PIcmp6CreateFile create6_;
93     PIcmp6SendEcho2 send6_;
94     char* data_;
95     uint32_t dlen_;
96     char* reply_;
97     uint32_t rlen_;
98     bool valid_;
99 };
100 
101 } // namespace rtc
102 
103 #endif // WEBRTC_WIN
104 
105 #endif // WEBRTC_BASE_WINPING_H__
106