1 /*
2 * Copyright (C) 2016, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <memory>
18 #include <string>
19 #include <vector>
20
21 #include <linux/netlink.h>
22 #include <linux/nl80211.h>
23
24 #include <gtest/gtest.h>
25
26 #include "wificond/net/netlink_utils.h"
27 #include "wificond/tests/mock_netlink_manager.h"
28
29 using std::string;
30 using std::unique_ptr;
31 using std::vector;
32 using testing::DoAll;
33 using testing::NiceMock;
34 using testing::Return;
35 using testing::_;
36
37 namespace android {
38 namespace wificond {
39
40 namespace {
41
42 constexpr uint8_t kFakeMaxNumScanSSIDs = 10;
43 constexpr uint8_t kFakeMaxNumSchedScanSSIDs = 16;
44 constexpr uint8_t kFakeMaxMatchSets = 18;
45 constexpr uint16_t kFakeFamilyId = 14;
46 constexpr uint32_t kFakeFrequency1 = 2412;
47 constexpr uint32_t kFakeFrequency2 = 2437;
48 constexpr uint32_t kFakeFrequency3 = 2484;
49 constexpr uint32_t kFakeFrequency4 = 5200;
50 constexpr uint32_t kFakeFrequency5 = 5400;
51 constexpr uint32_t kFakeFrequency6 = 5600;
52 constexpr uint32_t kFakeSequenceNumber = 162;
53 constexpr uint16_t kFakeWiphyIndex = 8;
54 constexpr int kFakeErrorCode = EIO;
55 const char kFakeInterfaceName[] = "testif0";
56 const uint32_t kFakeInterfaceIndex = 34;
57 const uint32_t kFakeInterfaceIndex1 = 36;
58 const uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
59 const uint8_t kFakeInterfaceMacAddress1[] = {0x05, 0x04, 0xef, 0x27, 0x12, 0xff};
60
61 // Currently, control messages are only created by the kernel and sent to us.
62 // Therefore NL80211Packet doesn't have corresponding constructor.
63 // For test we manually create control messages using this helper function.
CreateControlMessageError(int error_code)64 NL80211Packet CreateControlMessageError(int error_code) {
65 vector<uint8_t> data;
66 data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0);
67 // Initialize length field.
68 nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data());
69 nl_header->nlmsg_len = data.size();
70 nl_header->nlmsg_type = NLMSG_ERROR;
71 nl_header->nlmsg_seq = kFakeSequenceNumber;
72 nl_header->nlmsg_pid = getpid();
73 int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN);
74 *error_field = -error_code;
75
76 return NL80211Packet(data);
77 }
78
CreateControlMessageAck()79 NL80211Packet CreateControlMessageAck() {
80 return CreateControlMessageError(0);
81 }
82
83 } // namespace
84
85 class NetlinkUtilsTest : public ::testing::Test {
86 protected:
87 std::unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_;
88 std::unique_ptr<NetlinkUtils> netlink_utils_;
89
SetUp()90 virtual void SetUp() {
91 netlink_manager_.reset(new NiceMock<MockNetlinkManager>());
92 netlink_utils_.reset(new NetlinkUtils(netlink_manager_.get()));
93
94 ON_CALL(*netlink_manager_,
95 GetSequenceNumber()).WillByDefault(Return(kFakeSequenceNumber));
96 ON_CALL(*netlink_manager_,
97 GetFamilyId()).WillByDefault(Return(kFakeFamilyId));
98 }
99 };
100
101 // This mocks the behavior of SendMessageAndGetResponses(), which returns a
102 // vector of NL80211Packet using passed in pointer.
ACTION_P(MakeupResponse,response)103 ACTION_P(MakeupResponse, response) {
104 // arg1 is the second parameter: vector<unique_ptr<const NL80211Packet>>* responses.
105 for (auto& pkt : response) {
106 arg1->push_back(unique_ptr<NL80211Packet>(new NL80211Packet(pkt)));
107 }
108 }
109
TEST_F(NetlinkUtilsTest,CanGetWiphyIndex)110 TEST_F(NetlinkUtilsTest, CanGetWiphyIndex) {
111 NL80211Packet new_wiphy(
112 netlink_manager_->GetFamilyId(),
113 NL80211_CMD_NEW_WIPHY,
114 netlink_manager_->GetSequenceNumber(),
115 getpid());
116 // Insert wiphy_index attribute.
117 NL80211Attr<uint32_t> wiphy_index_attr(NL80211_ATTR_WIPHY, kFakeWiphyIndex);
118 new_wiphy.AddAttribute(wiphy_index_attr);
119 // Mock a valid response from kernel.
120 vector<NL80211Packet> response = {new_wiphy};
121
122 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
123 WillOnce(DoAll(MakeupResponse(response), Return(true)));
124
125 uint32_t wiphy_index;
126 EXPECT_TRUE(netlink_utils_->GetWiphyIndex(&wiphy_index));
127 EXPECT_EQ(kFakeWiphyIndex, wiphy_index);
128 }
129
TEST_F(NetlinkUtilsTest,CanHandleGetWiphyIndexError)130 TEST_F(NetlinkUtilsTest, CanHandleGetWiphyIndexError) {
131 // Mock an error response from kernel.
132 vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
133
134 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
135 WillOnce(DoAll(MakeupResponse(response), Return(true)));
136
137 uint32_t wiphy_index;
138 EXPECT_FALSE(netlink_utils_->GetWiphyIndex(&wiphy_index));
139 }
140
TEST_F(NetlinkUtilsTest,CanSetIntrerfaceMode)141 TEST_F(NetlinkUtilsTest, CanSetIntrerfaceMode) {
142 // Mock a ACK response from kernel.
143 vector<NL80211Packet> response = {CreateControlMessageAck()};
144
145 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
146 WillOnce(DoAll(MakeupResponse(response), Return(true)));
147
148 EXPECT_TRUE(netlink_utils_->SetInterfaceMode(kFakeInterfaceIndex,
149 NetlinkUtils::STATION_MODE));
150 }
151
TEST_F(NetlinkUtilsTest,CanHandleSetIntrerfaceModeError)152 TEST_F(NetlinkUtilsTest, CanHandleSetIntrerfaceModeError) {
153 // Mock an error response from kernel.
154 vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
155
156 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
157 WillOnce(DoAll(MakeupResponse(response), Return(true)));
158
159 EXPECT_FALSE(netlink_utils_->SetInterfaceMode(kFakeInterfaceIndex,
160 NetlinkUtils::STATION_MODE));
161 }
162
TEST_F(NetlinkUtilsTest,CanGetInterfaces)163 TEST_F(NetlinkUtilsTest, CanGetInterfaces) {
164 NL80211Packet new_interface(
165 netlink_manager_->GetFamilyId(),
166 NL80211_CMD_NEW_INTERFACE,
167 netlink_manager_->GetSequenceNumber(),
168 getpid());
169 // Insert interface name attribute.
170 NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
171 new_interface.AddAttribute(if_name_attr);
172 // Insert interface index attribute.
173 NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
174 new_interface.AddAttribute(if_index_attr);
175 // Insert mac address attribute.
176 std::vector<uint8_t> if_mac_addr;
177 if_mac_addr.assign(
178 kFakeInterfaceMacAddress,
179 kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
180 NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
181 new_interface.AddAttribute(if_mac_attr);
182
183 // Mock a valid response from kernel.
184 vector<NL80211Packet> response = {new_interface};
185
186 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
187 WillOnce(DoAll(MakeupResponse(response), Return(true)));
188
189 vector<InterfaceInfo> interfaces;
190 EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
191 EXPECT_TRUE(interfaces.size() == 1);
192 EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].index);
193 EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
194 EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
195 }
196
TEST_F(NetlinkUtilsTest,SkipsPseudoDevicesWhenGetInterfaces)197 TEST_F(NetlinkUtilsTest, SkipsPseudoDevicesWhenGetInterfaces) {
198 // This might be a psuedo p2p interface without any interface index/name
199 // attributes.
200 NL80211Packet psuedo_interface(
201 netlink_manager_->GetFamilyId(),
202 NL80211_CMD_NEW_INTERFACE,
203 netlink_manager_->GetSequenceNumber(),
204 getpid());
205 psuedo_interface.AddAttribute(NL80211Attr<uint64_t>(
206 NL80211_ATTR_WDEV, 0));
207
208 // This is a regular client interface.
209 NL80211Packet expected_interface(
210 netlink_manager_->GetFamilyId(),
211 NL80211_CMD_NEW_INTERFACE,
212 netlink_manager_->GetSequenceNumber(),
213 getpid());
214 expected_interface.AddAttribute(NL80211Attr<string>(
215 NL80211_ATTR_IFNAME, string(kFakeInterfaceName)));
216 expected_interface.AddAttribute(NL80211Attr<uint32_t>(
217 NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
218 std::vector<uint8_t> if_mac_addr;
219 if_mac_addr.assign(
220 kFakeInterfaceMacAddress,
221 kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
222 expected_interface.AddAttribute(
223 NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
224
225 // Kernel can send us the pseduo interface packet first
226 vector<NL80211Packet> response = {psuedo_interface, expected_interface};
227
228 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
229 WillOnce(DoAll(MakeupResponse(response), Return(true)));
230
231 vector<InterfaceInfo> interfaces;
232 EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
233 EXPECT_TRUE(interfaces.size() == 1);
234 EXPECT_EQ(kFakeInterfaceIndex, interfaces[0].index);
235 EXPECT_EQ(string(kFakeInterfaceName), interfaces[0].name);
236 EXPECT_EQ(if_mac_addr, interfaces[0].mac_address);
237 }
238
TEST_F(NetlinkUtilsTest,HandleP2p0WhenGetInterfaces)239 TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaces) {
240 NL80211Packet new_interface(
241 netlink_manager_->GetFamilyId(),
242 NL80211_CMD_NEW_INTERFACE,
243 netlink_manager_->GetSequenceNumber(),
244 getpid());
245 // Insert interface name attribute.
246 NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
247 new_interface.AddAttribute(if_name_attr);
248 // Insert interface index attribute.
249 new_interface.AddAttribute(
250 NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
251 // Insert mac address attribute.
252 std::vector<uint8_t> if_mac_addr(
253 kFakeInterfaceMacAddress,
254 kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
255 new_interface.AddAttribute(
256 NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
257
258 // Create a new interface packet for p2p0.
259 NL80211Packet new_interface_p2p0(
260 netlink_manager_->GetFamilyId(),
261 NL80211_CMD_NEW_INTERFACE,
262 netlink_manager_->GetSequenceNumber(),
263 getpid());
264
265 // Insert interface name attribute.
266 new_interface_p2p0.AddAttribute(
267 NL80211Attr<string>(NL80211_ATTR_IFNAME, "p2p0"));
268 // Insert interface index attribute.
269 new_interface_p2p0.AddAttribute(
270 NL80211Attr<uint32_t>(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex1));
271 // Insert mac address attribute.
272 std::vector<uint8_t> if_mac_addr_p2p(
273 kFakeInterfaceMacAddress1,
274 kFakeInterfaceMacAddress1 + sizeof(kFakeInterfaceMacAddress1));
275 new_interface_p2p0.AddAttribute(
276 NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr_p2p));
277
278 // Mock response from kernel, including 2 interfaces.
279 vector<NL80211Packet> response = {new_interface_p2p0, new_interface};
280
281 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
282 WillOnce(DoAll(MakeupResponse(response), Return(true)));
283
284 vector<InterfaceInfo> interfaces;
285 EXPECT_TRUE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
286 EXPECT_TRUE(interfaces.size() == 2);
287
288 EXPECT_EQ(kFakeInterfaceIndex1, interfaces[0].index);
289 EXPECT_EQ(string("p2p0"), interfaces[0].name);
290 EXPECT_EQ(if_mac_addr_p2p, interfaces[0].mac_address);
291
292 EXPECT_EQ(kFakeInterfaceIndex, interfaces[1].index);
293 EXPECT_EQ(string(kFakeInterfaceName), interfaces[1].name);
294 EXPECT_EQ(if_mac_addr, interfaces[1].mac_address);
295 }
296
TEST_F(NetlinkUtilsTest,CanHandleGetInterfacesError)297 TEST_F(NetlinkUtilsTest, CanHandleGetInterfacesError) {
298 // Mock an error response from kernel.
299 vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
300
301 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
302 WillOnce(DoAll(MakeupResponse(response), Return(true)));
303
304 vector<InterfaceInfo> interfaces;
305 EXPECT_FALSE(netlink_utils_->GetInterfaces(kFakeWiphyIndex, &interfaces));
306 }
307
TEST_F(NetlinkUtilsTest,CanGetWiphyInfo)308 TEST_F(NetlinkUtilsTest, CanGetWiphyInfo) {
309 NL80211Packet new_wiphy(
310 netlink_manager_->GetFamilyId(),
311 NL80211_CMD_NEW_WIPHY,
312 netlink_manager_->GetSequenceNumber(),
313 getpid());
314 new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
315 kFakeWiphyIndex));
316
317 // Insert band information to mock netlink response.
318
319 NL80211NestedAttr freq_2g_1(1);
320 NL80211NestedAttr freq_2g_2(2);
321 NL80211NestedAttr freq_2g_3(3);
322 NL80211NestedAttr freq_5g_1(4);
323 NL80211NestedAttr freq_5g_2(5);
324 NL80211NestedAttr freq_dfs_1(6);
325 freq_2g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
326 kFakeFrequency1));
327 freq_2g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
328 kFakeFrequency2));
329 freq_2g_3.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
330 kFakeFrequency3));
331 freq_5g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
332 kFakeFrequency4));
333 freq_5g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
334 kFakeFrequency5));
335 // DFS frequency.
336 freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
337 kFakeFrequency6));
338 freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(
339 NL80211_FREQUENCY_ATTR_DFS_STATE,
340 NL80211_DFS_USABLE));
341
342 NL80211NestedAttr band_2g_freqs(NL80211_BAND_ATTR_FREQS);
343 NL80211NestedAttr band_5g_freqs(NL80211_BAND_ATTR_FREQS);
344 band_2g_freqs.AddAttribute(freq_2g_1);
345 band_2g_freqs.AddAttribute(freq_2g_2);
346 band_2g_freqs.AddAttribute(freq_2g_3);
347 band_5g_freqs.AddAttribute(freq_5g_1);
348 band_5g_freqs.AddAttribute(freq_5g_2);
349 band_5g_freqs.AddAttribute(freq_dfs_1);
350
351 NL80211NestedAttr band_2g_attr(1);
352 NL80211NestedAttr band_5g_attr(2);
353 band_2g_attr.AddAttribute(band_2g_freqs);
354 band_5g_attr.AddAttribute(band_5g_freqs);
355
356 NL80211NestedAttr band_attr(NL80211_ATTR_WIPHY_BANDS);
357 band_attr.AddAttribute(band_2g_attr);
358 band_attr.AddAttribute(band_5g_attr);
359
360 new_wiphy.AddAttribute(band_attr);
361
362 // Insert scan capabilities to mock netlink response.
363 new_wiphy.AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
364 kFakeMaxNumScanSSIDs));
365 new_wiphy.AddAttribute(NL80211Attr<uint8_t>(
366 NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
367 kFakeMaxNumSchedScanSSIDs));
368 new_wiphy.AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_MATCH_SETS,
369 kFakeMaxMatchSets));
370
371 // Insert wiphy features to mock netlink response.
372 new_wiphy.AddAttribute(NL80211Attr<uint32_t>(
373 NL80211_ATTR_FEATURE_FLAGS,
374 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR));
375
376 vector<NL80211Packet> response = {new_wiphy};
377
378 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
379 WillOnce(DoAll(MakeupResponse(response), Return(true)));
380
381 BandInfo band_info;
382 ScanCapabilities scan_capabilities;
383 WiphyFeatures wiphy_features;
384 EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
385 &band_info,
386 &scan_capabilities,
387 &wiphy_features));
388
389 // Verify band information.
390 vector<uint32_t> band_2g_expected = {kFakeFrequency1,
391 kFakeFrequency2, kFakeFrequency3};
392 vector<uint32_t> band_5g_expected = {kFakeFrequency4, kFakeFrequency5};
393 vector<uint32_t> band_dfs_expected = {kFakeFrequency6};
394 EXPECT_EQ(band_info.band_2g, band_2g_expected);
395 EXPECT_EQ(band_info.band_5g, band_5g_expected);
396 EXPECT_EQ(band_info.band_dfs, band_dfs_expected);
397
398 // Verify scan capabilities.
399 EXPECT_EQ(scan_capabilities.max_num_scan_ssids,
400 kFakeMaxNumScanSSIDs);
401 EXPECT_EQ(scan_capabilities.max_num_sched_scan_ssids,
402 kFakeMaxNumSchedScanSSIDs);
403 EXPECT_EQ(scan_capabilities.max_match_sets,
404 kFakeMaxMatchSets);
405
406 // Verify wiphy features.
407 EXPECT_TRUE(wiphy_features.supports_random_mac_oneshot_scan);
408 EXPECT_FALSE(wiphy_features.supports_random_mac_sched_scan);
409 }
410
TEST_F(NetlinkUtilsTest,CanHandleGetWiphyInfoError)411 TEST_F(NetlinkUtilsTest, CanHandleGetWiphyInfoError) {
412 // Mock an error response from kernel.
413 vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
414
415 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
416 WillOnce(DoAll(MakeupResponse(response), Return(true)));
417
418 BandInfo band_info;
419 ScanCapabilities scan_capabilities;
420 WiphyFeatures wiphy_features;
421 EXPECT_FALSE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
422 &band_info,
423 &scan_capabilities,
424 &wiphy_features));
425 }
426
427 } // namespace wificond
428 } // namespace android
429