-
Notifications
You must be signed in to change notification settings - Fork 5
/
ProxyWifiService.hpp
243 lines (199 loc) · 9.91 KB
/
ProxyWifiService.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <Windows.h>
#include <windot11.h>
#include <wlantypes.h>
namespace ProxyWifi {
/// @brief The mode controlling how the proxy operates.
enum class OperationMode
{
/// @brief Normal (proxied) mode.
///
/// The proxy provides real results using available hardware on the host. If
/// no suitable hardware is available, most operations are likely to fail.
Normal,
/// @brief Simulated mode.
///
/// The proxy simulates results, not using hardware on the host, even if it
/// is present and available.
Simulated,
};
/// @brief Represents a host Wi-Fi proxy service.
class ProxyWifiService
{
public:
virtual ~ProxyWifiService() = default;
/// @brief Start the proxy.
///
/// This creates the transport and begins accepting connections on it. Until
/// Start() is called, the proxy is inactive and does not accept connections.
virtual void Start() = 0;
/// @brief Stop the proxy.
///
/// Stop the proxy if it is started. This will sever all existing connections
/// to the proxy and destroy the transport. Following execution of this call,
/// the proxy will no longer accept new connections. It may be restarted
/// using Start().
virtual void Stop() = 0;
};
/// @brief Indicate the status of a guest initiated operation
enum class OperationStatus
{
Succeeded, ///< The operation was completed successfully and success will be indicated to the guest
Failed, ///< The operation failed and failure will be indicated to the guest
Denied ///< The operation was denied by the client and failure will be indicated to the guest
};
/// @brief List basic information about a Wi-Fi network
struct WifiNetworkInfo
{
WifiNetworkInfo() = default;
WifiNetworkInfo(const DOT11_SSID& ssid, const DOT11_MAC_ADDRESS& bssid);
DOT11_SSID ssid = {};
DOT11_MAC_ADDRESS bssid = {};
};
/// @brief Indicate the impact a guest requested operation will have on the host
enum class OperationType
{
GuestDirected, ///< The guest is directing this operation, and the host state will change to accomodate it
HostMirroring ///< The guest was only replicating the state of the host, the host state won't change as a result of this request
};
/// @brief Observer class that get notified on host or guest events
/// Client should inherit from it and override method to handle notifications
class ProxyWifiObserver
{
public:
virtual ~ProxyWifiObserver() = default;
struct ConnectRequestArgs
{
DOT11_SSID ssid;
};
struct ConnectCompleteArgs
{
GUID interfaceGuid;
DOT11_SSID ssid;
DOT11_AUTH_ALGORITHM authAlgo;
};
struct DisconnectRequestArgs
{
DOT11_SSID ssid;
};
struct DisconnectCompleteArgs
{
GUID interfaceGuid;
DOT11_SSID ssid;
};
/// @brief Indicate whether proxy_wifi should proceed with a guest request or answer immediately with a failure
enum class Authorization
{
Approve,
Deny
};
/// @brief An host WiFi interface connected to a network
virtual void OnHostConnection(const ConnectCompleteArgs& /* connectionInfo */) noexcept
{
}
/// @brief An host WiFi interface disconnected from a network
virtual void OnHostDisconnection(const DisconnectCompleteArgs& /* disconnectionInfo */) noexcept
{
}
/// @brief The guest requested a connection to a network
/// @return Return `Authorization::Approve` to let the connection proceed, return `Authorization::Deny` to answer to the guest
/// with a failure If `type == OperationType::HostMirroring`, an host inteface is already connected to the network, otherwise,
/// one will be connected. The connection won't proceed until the callback returns
virtual Authorization AuthorizeGuestConnectionRequest(OperationType /* type */, const ConnectRequestArgs& /* connectionInfo */) noexcept
{
return Authorization::Approve;
}
/// @brief A guest connection request was processed
/// If `type == OperationType::HostMirroring`, an host inteface was already connected to the network, otherwise, one has been
/// be connected The response won't be sent to the guest until this callback returns
virtual void OnGuestConnectionCompletion(OperationType /* type */, OperationStatus /* status */, const ConnectCompleteArgs& /* connectionInfo */) noexcept
{
}
/// @brief The guest requested a disconnection from the connected network
/// If `type == OperationType::HostMirroring`, the host won't be impacted, otherwise, a matching host interface will be
/// disconnected The disconnection won't proceed until the callback returns
virtual void OnGuestDisconnectionRequest(OperationType /* type */, const DisconnectRequestArgs& /* connectionInfo */) noexcept
{
}
/// @brief A guest disconnection request was processed
/// If `type == OperationType::HostMirroring`, this was a no-op for the host, otherwise, a matching host interface has been
/// disconnected The response won't be sent to the guest until this callback returns
virtual void OnGuestDisconnectionCompletion(OperationType /* type */, OperationStatus /* status */, const DisconnectCompleteArgs& /* disconnectionInfo */) noexcept
{
}
/// @brief The guest requested a scan
/// The scan won't start on the host until this callback returns
virtual void OnGuestScanRequest() noexcept
{
}
/// @brief A guest scan request was processed
/// The scan results won't be sent to the guest until this callback returns
virtual void OnGuestScanCompletion(OperationStatus /* status */) noexcept
{
}
};
/// @brief Type of the callback providing a list of networks that will be simulated by the Wi-Fi proxy
/// They will be shown as open networks, and are considered as permanently connected for the purpose of notifications
using FakeNetworkProvider = std::function<std::vector<WifiNetworkInfo>()>;
/// @brief Guid used in notifications concerning the provided fake networks
/// 1b57e649-a1df-482f-85c2-a16063836418
constexpr GUID FakeInterfaceGuid{0x1b57e649, 0xa1df, 0x482f, {0x85, 0xc2, 0xa, 0x6, 0x6, 0x8, 0x6, 0x18}};
/// @brief Default request/response port used for both HyperV and TCP based Wi-Fi
/// proxies if none is explicitly specified.
constexpr unsigned short RequestResponsePortDefault = 12345;
/// @brief Default notification port used for both HyperV and TCP based Wi-Fi
/// proxies if none is explicitly specified.
constexpr unsigned short NotificationPortDefault = 12346;
/// @brief Settings controlling a HyperV based Wi-Fi proxy.
struct ProxyWifiHyperVSettings
{
/// @brief Construct a setting object to configure a new Wifi Proxy using an Hyper V transport
/// @param guestVmId The vm id of the HyperV container guest from which to allow connections.
/// @param requestResponsePort The HyperV socket port number for the request/response communication channel.
/// @param notificationPort The HyperV socket port number for the notification communication channel.
/// @param mode The mode of operation used to emulate or virtualize Wifi
ProxyWifiHyperVSettings(const GUID& guestVmId, unsigned short requestResponsePort, unsigned short notificationPort, OperationMode mode);
/// @brief Construct a setting object to configure a new Wifi Proxy using an Hyper V transport
/// @param guestVmId The vm id of the HyperV container guest from which to allow connections
explicit ProxyWifiHyperVSettings(const GUID& guestVmId);
/// @brief The HyperV socket port number for the request/response communication channel.
unsigned short RequestResponsePort = RequestResponsePortDefault;
/// @brief The HyperV socket port number for the notification communication channel.
unsigned short NotificationPort = NotificationPortDefault;
/// @brief The vm id of the HyperV container guest from which to allow connections.
const GUID GuestVmId{};
/// @brief The initial mode for the proxy
const OperationMode ProxyMode = OperationMode::Normal;
};
/// @brief Settings controlling a TCP based Wi-Fi proxy.
struct ProxyWifiTcpSettings
{
/// @brief Construct a setting object to configure a new Wifi Proxy using a Tcp transport
/// @param listenIp The TCP/IP address for the proxy to listen for connection.
/// @param requestResponsePort The TCP/IP port number for the request/response communication channel.
/// @param notificationPort The TCP/IP port number for the notification communication channel.
/// @param mode The mode of operation used to emulate or virtualize Wifi
ProxyWifiTcpSettings(std::string listenIp, unsigned short requestResponsePort, unsigned short notificationPort, OperationMode mode);
/// @brief Construct a setting object to configure a new Wifi Proxy using a Tcp transport
/// @param listenIp The TCP/IP address for the proxy to listen for connection.
explicit ProxyWifiTcpSettings(std::string listenIp);
/// @brief The TCP/IP port number for the request/response communication channel.
unsigned short RequestResponsePort = RequestResponsePortDefault;
/// @brief The TCP/IP port number for the notification communication channel.
unsigned short NotificationPort = NotificationPortDefault;
/// @brief The TCP/IP address for the proxy to listen for connection.
const std::string ListenIp;
/// @brief The initial mode for the proxy
const OperationMode ProxyMode = OperationMode::Normal;
};
std::unique_ptr<ProxyWifiService> BuildProxyWifiService(
const ProxyWifiHyperVSettings& settings, FakeNetworkProvider fakeNetworkCallback = {}, ProxyWifiObserver* pObserver = nullptr);
std::unique_ptr<ProxyWifiService> BuildProxyWifiService(
const ProxyWifiTcpSettings& settings, FakeNetworkProvider fakeNetworkCallback = {}, ProxyWifiObserver* pObserver = nullptr);
} // namespace ProxyWifi