2 * Copyright (C) 2016, The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <linux/netlink.h>
22 #include <linux/nl80211.h>
24 #include <gtest/gtest.h>
26 #include "wificond/net/netlink_utils.h"
27 #include "wificond/tests/mock_netlink_manager.h"
30 using std::unique_ptr;
33 using testing::NiceMock;
34 using testing::Return;
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 uint8_t kFakeInterfaceMacAddress[] = {0x45, 0x54, 0xad, 0x67, 0x98, 0xf6};
59 // Currently, control messages are only created by the kernel and sent to us.
60 // Therefore NL80211Packet doesn't have corresponding constructor.
61 // For test we manually create control messages using this helper function.
62 NL80211Packet CreateControlMessageError(int error_code) {
64 data.resize(NLMSG_HDRLEN + NLA_ALIGN(sizeof(int)), 0);
65 // Initialize length field.
66 nlmsghdr* nl_header = reinterpret_cast<nlmsghdr*>(data.data());
67 nl_header->nlmsg_len = data.size();
68 nl_header->nlmsg_type = NLMSG_ERROR;
69 nl_header->nlmsg_seq = kFakeSequenceNumber;
70 nl_header->nlmsg_pid = getpid();
71 int* error_field = reinterpret_cast<int*>(data.data() + NLMSG_HDRLEN);
72 *error_field = -error_code;
74 return NL80211Packet(data);
79 class NetlinkUtilsTest : public ::testing::Test {
81 std::unique_ptr<NiceMock<MockNetlinkManager>> netlink_manager_;
82 std::unique_ptr<NetlinkUtils> netlink_utils_;
84 virtual void SetUp() {
85 netlink_manager_.reset(new NiceMock<MockNetlinkManager>());
86 netlink_utils_.reset(new NetlinkUtils(netlink_manager_.get()));
88 ON_CALL(*netlink_manager_,
89 GetSequenceNumber()).WillByDefault(Return(kFakeSequenceNumber));
90 ON_CALL(*netlink_manager_,
91 GetFamilyId()).WillByDefault(Return(kFakeFamilyId));
95 // This mocks the behavior of SendMessageAndGetResponses(), which returns a
96 // vector of NL80211Packet using passed in pointer.
97 ACTION_P(MakeupResponse, response) {
98 // arg1 is the second parameter: vector<unique_ptr<const NL80211Packet>>* responses.
99 for (auto& pkt : response) {
100 arg1->push_back(unique_ptr<NL80211Packet>(new NL80211Packet(pkt)));
104 TEST_F(NetlinkUtilsTest, CanGetWiphyIndex) {
105 NL80211Packet new_wiphy(
106 netlink_manager_->GetFamilyId(),
107 NL80211_CMD_NEW_WIPHY,
108 netlink_manager_->GetSequenceNumber(),
110 // Insert wiphy_index attribute.
111 NL80211Attr<uint32_t> wiphy_index_attr(NL80211_ATTR_WIPHY, kFakeWiphyIndex);
112 new_wiphy.AddAttribute(wiphy_index_attr);
113 // Mock a valid response from kernel.
114 vector<NL80211Packet> response = {new_wiphy};
116 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
117 WillOnce(DoAll(MakeupResponse(response), Return(true)));
119 uint32_t wiphy_index;
120 EXPECT_TRUE(netlink_utils_->GetWiphyIndex(&wiphy_index));
121 EXPECT_EQ(kFakeWiphyIndex, wiphy_index);
124 TEST_F(NetlinkUtilsTest, CanHandleGetWiphyIndexError) {
125 // Mock an error response from kernel.
126 vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
128 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
129 WillOnce(DoAll(MakeupResponse(response), Return(true)));
131 uint32_t wiphy_index;
132 EXPECT_FALSE(netlink_utils_->GetWiphyIndex(&wiphy_index));
135 TEST_F(NetlinkUtilsTest, CanGetInterfaceInfo) {
136 NL80211Packet new_interface(
137 netlink_manager_->GetFamilyId(),
138 NL80211_CMD_NEW_INTERFACE,
139 netlink_manager_->GetSequenceNumber(),
141 // Insert interface name attribute.
142 NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
143 new_interface.AddAttribute(if_name_attr);
144 // Insert interface index attribute.
145 NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
146 new_interface.AddAttribute(if_index_attr);
147 // Insert mac address attribute.
148 std::vector<uint8_t> if_mac_addr;
150 kFakeInterfaceMacAddress,
151 kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
152 NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
153 new_interface.AddAttribute(if_mac_attr);
155 // Mock a valid response from kernel.
156 vector<NL80211Packet> response = {new_interface};
158 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
159 WillOnce(DoAll(MakeupResponse(response), Return(true)));
161 string interface_name;
162 uint32_t interface_index;
163 vector<uint8_t> interface_mac_addr;
164 EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
167 &interface_mac_addr));
168 EXPECT_EQ(string(kFakeInterfaceName), interface_name);
169 EXPECT_EQ(kFakeInterfaceIndex, interface_index);
170 EXPECT_EQ(if_mac_addr, interface_mac_addr);
173 TEST_F(NetlinkUtilsTest, HandlesPseudoDevicesInInterfaceInfoQuery) {
174 // Some kernels will have extra responses ahead of the expected packet.
175 NL80211Packet psuedo_interface(
176 netlink_manager_->GetFamilyId(),
177 NL80211_CMD_NEW_INTERFACE,
178 netlink_manager_->GetSequenceNumber(),
180 psuedo_interface.AddAttribute(NL80211Attr<uint64_t>(
181 NL80211_ATTR_WDEV, 0));
183 // This is the packet we're looking for
184 NL80211Packet expected_interface(
185 netlink_manager_->GetFamilyId(),
186 NL80211_CMD_NEW_INTERFACE,
187 netlink_manager_->GetSequenceNumber(),
189 expected_interface.AddAttribute(NL80211Attr<string>(
190 NL80211_ATTR_IFNAME, string(kFakeInterfaceName)));
191 expected_interface.AddAttribute(NL80211Attr<uint32_t>(
192 NL80211_ATTR_IFINDEX, kFakeInterfaceIndex));
193 std::vector<uint8_t> if_mac_addr;
195 kFakeInterfaceMacAddress,
196 kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
197 expected_interface.AddAttribute(
198 NL80211Attr<vector<uint8_t>>(NL80211_ATTR_MAC, if_mac_addr));
200 // Kernel can send us the pseduo interface packet first
201 vector<NL80211Packet> response = {psuedo_interface, expected_interface};
203 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
204 WillOnce(DoAll(MakeupResponse(response), Return(true)));
206 string interface_name;
207 uint32_t interface_index;
208 vector<uint8_t> interface_mac_addr;
209 EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(
210 kFakeWiphyIndex, &interface_name, &interface_index, &interface_mac_addr));
211 EXPECT_EQ(string(kFakeInterfaceName), interface_name);
212 EXPECT_EQ(kFakeInterfaceIndex, interface_index);
213 EXPECT_EQ(if_mac_addr, interface_mac_addr);
216 TEST_F(NetlinkUtilsTest, HandleP2p0WhenGetInterfaceInfo) {
217 NL80211Packet new_interface(
218 netlink_manager_->GetFamilyId(),
219 NL80211_CMD_NEW_INTERFACE,
220 netlink_manager_->GetSequenceNumber(),
222 // Insert interface name attribute.
223 NL80211Attr<string> if_name_attr(NL80211_ATTR_IFNAME, string(kFakeInterfaceName));
224 new_interface.AddAttribute(if_name_attr);
225 // Insert interface index attribute.
226 NL80211Attr<uint32_t> if_index_attr(NL80211_ATTR_IFINDEX, kFakeInterfaceIndex);
227 new_interface.AddAttribute(if_index_attr);
228 // Insert mac address attribute.
229 std::vector<uint8_t> if_mac_addr;
231 kFakeInterfaceMacAddress,
232 kFakeInterfaceMacAddress + sizeof(kFakeInterfaceMacAddress));
233 NL80211Attr<vector<uint8_t>> if_mac_attr(NL80211_ATTR_MAC, if_mac_addr);
234 new_interface.AddAttribute(if_mac_attr);
236 // Create a new interface packet for p2p0.
237 NL80211Packet new_interface_p2p0(
238 netlink_manager_->GetFamilyId(),
239 NL80211_CMD_NEW_INTERFACE,
240 netlink_manager_->GetSequenceNumber(),
242 NL80211Attr<string> if_name_attr_p2p0(NL80211_ATTR_IFNAME, "p2p0");
243 new_interface_p2p0.AddAttribute(if_name_attr_p2p0);
244 // Mock response from kernel, including 2 interfaces.
245 vector<NL80211Packet> response = {new_interface_p2p0, new_interface};
247 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
248 WillOnce(DoAll(MakeupResponse(response), Return(true)));
250 string interface_name;
251 uint32_t interface_index;
252 vector<uint8_t> interface_mac_addr;
253 EXPECT_TRUE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
256 &interface_mac_addr));
257 EXPECT_EQ(string(kFakeInterfaceName), interface_name);
258 EXPECT_EQ(kFakeInterfaceIndex, interface_index);
259 EXPECT_EQ(if_mac_addr, interface_mac_addr);
262 TEST_F(NetlinkUtilsTest, CanHandleGetInterfaceInfoError) {
263 // Mock an error response from kernel.
264 vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
266 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
267 WillOnce(DoAll(MakeupResponse(response), Return(true)));
269 string interface_name;
270 uint32_t interface_index;
271 vector<uint8_t> interface_mac_addr;
272 EXPECT_FALSE(netlink_utils_->GetInterfaceInfo(kFakeWiphyIndex,
275 &interface_mac_addr));
278 TEST_F(NetlinkUtilsTest, CanGetWiphyInfo) {
279 NL80211Packet new_wiphy(
280 netlink_manager_->GetFamilyId(),
281 NL80211_CMD_NEW_WIPHY,
282 netlink_manager_->GetSequenceNumber(),
284 new_wiphy.AddAttribute(NL80211Attr<uint32_t>(NL80211_ATTR_WIPHY,
287 // Insert band information to mock netlink response.
289 NL80211NestedAttr freq_2g_1(1);
290 NL80211NestedAttr freq_2g_2(2);
291 NL80211NestedAttr freq_2g_3(3);
292 NL80211NestedAttr freq_5g_1(4);
293 NL80211NestedAttr freq_5g_2(5);
294 NL80211NestedAttr freq_dfs_1(6);
295 freq_2g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
297 freq_2g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
299 freq_2g_3.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
301 freq_5g_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
303 freq_5g_2.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
306 freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(NL80211_FREQUENCY_ATTR_FREQ,
308 freq_dfs_1.AddAttribute(NL80211Attr<uint32_t>(
309 NL80211_FREQUENCY_ATTR_DFS_STATE,
310 NL80211_DFS_USABLE));
312 NL80211NestedAttr band_2g_freqs(NL80211_BAND_ATTR_FREQS);
313 NL80211NestedAttr band_5g_freqs(NL80211_BAND_ATTR_FREQS);
314 band_2g_freqs.AddAttribute(freq_2g_1);
315 band_2g_freqs.AddAttribute(freq_2g_2);
316 band_2g_freqs.AddAttribute(freq_2g_3);
317 band_5g_freqs.AddAttribute(freq_5g_1);
318 band_5g_freqs.AddAttribute(freq_5g_2);
319 band_5g_freqs.AddAttribute(freq_dfs_1);
321 NL80211NestedAttr band_2g_attr(1);
322 NL80211NestedAttr band_5g_attr(2);
323 band_2g_attr.AddAttribute(band_2g_freqs);
324 band_5g_attr.AddAttribute(band_5g_freqs);
326 NL80211NestedAttr band_attr(NL80211_ATTR_WIPHY_BANDS);
327 band_attr.AddAttribute(band_2g_attr);
328 band_attr.AddAttribute(band_5g_attr);
330 new_wiphy.AddAttribute(band_attr);
332 // Insert scan capabilities to mock netlink response.
333 new_wiphy.AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
334 kFakeMaxNumScanSSIDs));
335 new_wiphy.AddAttribute(NL80211Attr<uint8_t>(
336 NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
337 kFakeMaxNumSchedScanSSIDs));
338 new_wiphy.AddAttribute(NL80211Attr<uint8_t>(NL80211_ATTR_MAX_MATCH_SETS,
341 // Insert wiphy features to mock netlink response.
342 new_wiphy.AddAttribute(NL80211Attr<uint32_t>(
343 NL80211_ATTR_FEATURE_FLAGS,
344 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR));
346 vector<NL80211Packet> response = {new_wiphy};
348 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
349 WillOnce(DoAll(MakeupResponse(response), Return(true)));
352 ScanCapabilities scan_capabilities;
353 WiphyFeatures wiphy_features;
354 EXPECT_TRUE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
359 // Verify band information.
360 vector<uint32_t> band_2g_expected = {kFakeFrequency1,
361 kFakeFrequency2, kFakeFrequency3};
362 vector<uint32_t> band_5g_expected = {kFakeFrequency4, kFakeFrequency5};
363 vector<uint32_t> band_dfs_expected = {kFakeFrequency6};
364 EXPECT_EQ(band_info.band_2g, band_2g_expected);
365 EXPECT_EQ(band_info.band_5g, band_5g_expected);
366 EXPECT_EQ(band_info.band_dfs, band_dfs_expected);
368 // Verify scan capabilities.
369 EXPECT_EQ(scan_capabilities.max_num_scan_ssids,
370 kFakeMaxNumScanSSIDs);
371 EXPECT_EQ(scan_capabilities.max_num_sched_scan_ssids,
372 kFakeMaxNumSchedScanSSIDs);
373 EXPECT_EQ(scan_capabilities.max_match_sets,
376 // Verify wiphy features.
377 EXPECT_TRUE(wiphy_features.supports_random_mac_oneshot_scan);
378 EXPECT_FALSE(wiphy_features.supports_random_mac_sched_scan);
381 TEST_F(NetlinkUtilsTest, CanHandleGetWiphyInfoError) {
382 // Mock an error response from kernel.
383 vector<NL80211Packet> response = {CreateControlMessageError(kFakeErrorCode)};
385 EXPECT_CALL(*netlink_manager_, SendMessageAndGetResponses(_, _)).
386 WillOnce(DoAll(MakeupResponse(response), Return(true)));
389 ScanCapabilities scan_capabilities;
390 WiphyFeatures wiphy_features;
391 EXPECT_FALSE(netlink_utils_->GetWiphyInfo(kFakeWiphyIndex,
397 } // namespace wificond
398 } // namespace android