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
19 #include <gtest/gtest.h>
20
21 #include <linux/nl80211.h>
22
23 #include "wificond/net/nl80211_attribute.h"
24
25 namespace android {
26 namespace wificond {
27
28 namespace {
29
30 const uint32_t kU8Value1 = 200;
31 const uint32_t kU16Value1 = 5000;
32 const uint32_t kU32Value1 = 250000;
33 const uint32_t kU32Value2 = 500000;
34 const std::string kIFName = "wlan0";
35 const uint8_t kMacAddress[] = {
36 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f
37 };
38
39 // This header contains invalid buffer length
40 const uint8_t kBrokenBuffer[] = {
41 0xff, 0xff, // nla_len = 0xffff
42 0x01, 0x11, // nla_type
43 0x15, 0x12, // payload
44 0x00, 0x00 // padding
45 };
46 const uint8_t kValidU32AttrBuffer[] = {
47 0x08, 0x00, // nla_len = 8
48 0x01, 0x00, // nla_type
49 0xf1, 0x12, 0x12, 0x2a // payload
50 };
51 const uint8_t kBufferContainsStringWithTrailingZero[] = {
52 0x0a, 0x00, // nla_len = 10
53 0x01, 0x00, // nla_type
54 'w', 'l', 'a', 'n', '0', '\0',
55 0x00, 0x00 // padding
56 };
57 const uint8_t kBufferContainsStringWithTrailingZeros[] = {
58 0x0c, 0x00, // nla_len = 12
59 0x01, 0x00, // nla_type
60 'w', 'l', 'a', 'n', '0', '\0', '\0', '\0'
61 };
62 const uint8_t kBufferContainsStringWithoutTrailingZero[] = {
63 0x09, 0x00, // nla_len = 9
64 0x01, 0x00, // nla_type
65 'w', 'l', 'a', 'n', '0',
66 0x00, 0x00, 0x00 // padding
67 };
68
69 const uint8_t kBufferContainsListOfAttributes[] = {
70 0x28, 0x00, // nla_len = 40
71 0x01, 0x00, // nla_type
72 // List of attributes:
73 // They have attribute id from 0 to N.
74 0x0a, 0x00, // nla_len = 10
75 0x00, 0x00, // nla_type = 0
76 'f', 'i', 'r', 's', 't','\0',
77 0x00, 0x00, // padding
78 0x0b, 0x00, // nla_len = 11
79 0x01, 0x00, // nla_type = 1
80 's', 'e', 'c', 'o', 'n', 'd','\0',
81 0x00, // padding
82 0x0a, 0x00, // nla_len = 10
83 0x02, 0x00, // nla_type = 2
84 't', 'h', 'i', 'r', 'd','\0',
85 0x00, 0x00, // padding
86 };
87
88 const uint8_t kBufferContainsListOfNestedAttributes[] = {
89 0x28, 0x00, // nla_len = 40
90 0x01, 0x00, // nla_type
91
92 // List of nested attributes:
93 // They have attribute id from 0 to N.
94
95 // Nested attribute 1:
96 0x0c, 0x00, // nla_len = 12
97 0x00, 0x00, // nla_type = 0
98 0x06, 0x00, // nla_len = 6
99 0x01, 0x00, // nla_type
100 0x05, 0x00, // uint16_t attribute with value 5
101 0x00, 0x00, // padding
102
103 // Nested attribute 2:
104 0x0c, 0x00, // nla_len = 12
105 0x01, 0x00, // nla_type = 1
106 0x08, 0x00, // nla_len = 8
107 0x01, 0x00, // nla_type
108 0x0a, 0x00,
109 0x00, 0x00, // uint32_t attribute with value 10
110
111 // Nested attribute 3:
112 0x0c, 0x00, // nla_len = 12
113 0x02, 0x00, // nla_type = 2
114 0x05, 0x00, // nla_len = 5
115 0x01, 0x00, // nla_type
116 0x08, 0x00, // uint8_t attribute with value 8
117 0x00, 0x00, // padding
118 };
119
120 } // namespace
121
TEST(NL80211AttributeTest,U8AttributesSeriallizeCorrectly)122 TEST(NL80211AttributeTest,U8AttributesSeriallizeCorrectly) {
123 NL80211Attr<uint8_t> u8_attr(1, kU8Value1);
124 EXPECT_EQ(u8_attr.GetValue(), kU8Value1);
125 }
126
TEST(NL80211AttributeTest,U16AttributesSeriallizeCorrectly)127 TEST(NL80211AttributeTest,U16AttributesSeriallizeCorrectly) {
128 NL80211Attr<uint16_t> u16_attr(1, kU16Value1);
129 EXPECT_EQ(u16_attr.GetValue(), kU16Value1);
130 }
131
TEST(NL80211AttributeTest,U32AttributesSeriallizeCorrectly)132 TEST(NL80211AttributeTest,U32AttributesSeriallizeCorrectly) {
133 NL80211Attr<uint32_t> u32_attr(1, kU32Value1);
134 EXPECT_EQ(u32_attr.GetValue(), kU32Value1);
135 }
136
TEST(NL80211AttributeTest,StringAttributesSeriallizeCorrectly)137 TEST(NL80211AttributeTest,StringAttributesSeriallizeCorrectly) {
138 NL80211Attr<std::string> str_attr(1, kIFName);
139 EXPECT_EQ(str_attr.GetValue(), kIFName);
140 }
141
TEST(NL80211AttributeTest,ByteVectorsSeriallizeCorrectly)142 TEST(NL80211AttributeTest, ByteVectorsSeriallizeCorrectly) {
143 std::vector<uint8_t> mac_address(
144 kMacAddress,
145 kMacAddress + sizeof(kMacAddress));
146 NL80211Attr<std::vector<uint8_t>> byte_vector_attr(1, mac_address);
147 EXPECT_EQ(byte_vector_attr.GetValue(), mac_address);
148 }
149
TEST(NL80211AttributeTest,CanGetNestedAttributes)150 TEST(NL80211AttributeTest, CanGetNestedAttributes) {
151 NL80211NestedAttr nested_attr(1);
152 NL80211Attr<uint32_t> u32_attr_1(1, kU32Value1);
153 NL80211Attr<uint32_t> u32_attr_2(2, kU32Value2);
154
155 nested_attr.AddAttribute(u32_attr_1);
156 nested_attr.AddAttribute(u32_attr_2);
157
158 EXPECT_TRUE(nested_attr.HasAttribute(1));
159 EXPECT_TRUE(nested_attr.HasAttribute(2));
160
161 uint32_t attr_value;
162 EXPECT_TRUE(nested_attr.GetAttributeValue(1, &attr_value));
163 EXPECT_EQ(attr_value, kU32Value1);
164 EXPECT_TRUE(nested_attr.GetAttributeValue(2, &attr_value));
165 EXPECT_EQ(attr_value, kU32Value2);
166 }
167
TEST(NL80211AttributeTest,CannotGetDoubleNestedAttributes)168 TEST(NL80211AttributeTest, CannotGetDoubleNestedAttributes) {
169 NL80211NestedAttr nested_attr(1);
170 NL80211NestedAttr deeper_nested_attr(2);
171 NL80211Attr<uint32_t> u32_attr_1(3, kU32Value1);
172
173 deeper_nested_attr.AddAttribute(u32_attr_1);
174 nested_attr.AddAttribute(deeper_nested_attr);
175
176 EXPECT_FALSE(nested_attr.HasAttribute(3));
177 }
178
TEST(NL80211AttributeTest,CannotGetMissingAttribute)179 TEST(NL80211AttributeTest, CannotGetMissingAttribute) {
180 NL80211NestedAttr nested_attr(1);
181 NL80211Attr<uint32_t> u32_attr_1(1, kU32Value1);
182
183 nested_attr.AddAttribute(u32_attr_1);
184
185 uint32_t attr_value;
186 EXPECT_FALSE(nested_attr.HasAttribute(2));
187 EXPECT_FALSE(nested_attr.GetAttributeValue(2, &attr_value));
188 }
189
TEST(NL80211AttributeTest,CannotGetAttributeWithWrongType)190 TEST(NL80211AttributeTest, CannotGetAttributeWithWrongType) {
191 NL80211NestedAttr nested_attr(1);
192 NL80211Attr<uint32_t> u32_attr_1(1, kU32Value1);
193
194 nested_attr.AddAttribute(u32_attr_1);
195
196 uint16_t attr_value;
197 EXPECT_TRUE(nested_attr.HasAttribute(1));
198 EXPECT_FALSE(nested_attr.GetAttributeValue(1, &attr_value));
199 }
200
201
TEST(NL80211AttributeTest,InvalidU32AttributeWithEmptyBuffer)202 TEST(NL80211AttributeTest, InvalidU32AttributeWithEmptyBuffer) {
203 std::vector<uint8_t> buffer;
204 NL80211Attr<uint32_t> invalid_attr(buffer);
205 EXPECT_FALSE(invalid_attr.IsValid());
206 }
207
TEST(NL80211AttributeTest,InvalidU32AttributeWithBrokenBuffer)208 TEST(NL80211AttributeTest, InvalidU32AttributeWithBrokenBuffer) {
209 std::vector<uint8_t> buffer(
210 kBrokenBuffer,
211 kBrokenBuffer + sizeof(kBrokenBuffer));
212 NL80211Attr<uint32_t> invalid_attr(buffer);
213 EXPECT_FALSE(invalid_attr.IsValid());
214 }
215
TEST(NL80211AttributeTest,InvalidU16AttributeWithU32Buffer)216 TEST(NL80211AttributeTest, InvalidU16AttributeWithU32Buffer) {
217 std::vector<uint8_t> buffer(
218 kValidU32AttrBuffer,
219 kValidU32AttrBuffer + sizeof(kValidU32AttrBuffer));
220 NL80211Attr<uint32_t> valid_attr(buffer);
221 NL80211Attr<uint16_t> invalid_attr(buffer);
222 EXPECT_TRUE(valid_attr.IsValid());
223 EXPECT_FALSE(invalid_attr.IsValid());
224 }
225
TEST(NL80211AttributeTest,InitStringAttributeWithTrailingZeroFromBuffer)226 TEST(NL80211AttributeTest, InitStringAttributeWithTrailingZeroFromBuffer) {
227 std::vector<uint8_t> buffer(
228 kBufferContainsStringWithTrailingZero,
229 kBufferContainsStringWithTrailingZero +
230 sizeof(kBufferContainsStringWithTrailingZero));
231 NL80211Attr<std::string> str_attr(buffer);
232 EXPECT_EQ("wlan0", str_attr.GetValue());
233 }
234
TEST(NL80211AttributeTest,InitStringAttributeWithTrailingZerosFromBuffer)235 TEST(NL80211AttributeTest, InitStringAttributeWithTrailingZerosFromBuffer) {
236 std::vector<uint8_t> buffer(
237 kBufferContainsStringWithTrailingZeros,
238 kBufferContainsStringWithTrailingZeros +
239 sizeof(kBufferContainsStringWithTrailingZeros));
240 NL80211Attr<std::string> str_attr(buffer);
241 EXPECT_EQ("wlan0", str_attr.GetValue());
242 }
243
TEST(NL80211AttributeTest,InitStringAttributeWithoutTrailingZeroFromBuffer)244 TEST(NL80211AttributeTest, InitStringAttributeWithoutTrailingZeroFromBuffer) {
245 std::vector<uint8_t> buffer(
246 kBufferContainsStringWithoutTrailingZero,
247 kBufferContainsStringWithoutTrailingZero +
248 sizeof(kBufferContainsStringWithoutTrailingZero));
249 NL80211Attr<std::string> str_attr(buffer);
250 EXPECT_EQ("wlan0", str_attr.GetValue());
251 }
252
TEST(NL80211AttributeTest,GetListOfStringsFromBuffer)253 TEST(NL80211AttributeTest, GetListOfStringsFromBuffer) {
254 std::vector<uint8_t> buffer(
255 kBufferContainsListOfAttributes,
256 kBufferContainsListOfAttributes +
257 sizeof(kBufferContainsListOfAttributes));
258 std::vector<std::string> strs;
259 std::vector<std::string> expected_strs = {"first", "second", "third"};
260 NL80211NestedAttr nested_attr(buffer);
261 nested_attr.GetListOfAttributeValues(&strs);
262 EXPECT_EQ(expected_strs, strs);
263 }
264
TEST(NL80211AttributeTest,GetListOfNestedAttributesFromBuffer)265 TEST(NL80211AttributeTest, GetListOfNestedAttributesFromBuffer) {
266 std::vector<uint8_t> buffer(
267 kBufferContainsListOfNestedAttributes,
268 kBufferContainsListOfNestedAttributes +
269 sizeof(kBufferContainsListOfNestedAttributes));
270 std::vector<NL80211NestedAttr> nested_attrs;
271 NL80211NestedAttr attr(buffer);
272 EXPECT_TRUE(attr.GetListOfNestedAttributes(&nested_attrs));
273 EXPECT_TRUE(nested_attrs.size() == 3);
274 uint16_t value1;
275 uint32_t value2;
276 uint8_t value3;
277 EXPECT_TRUE(nested_attrs[0].GetAttributeValue(1, &value1));
278 EXPECT_TRUE(nested_attrs[1].GetAttributeValue(1, &value2));
279 EXPECT_TRUE(nested_attrs[2].GetAttributeValue(1, &value3));
280 EXPECT_TRUE(value1 == 5);
281 EXPECT_TRUE(value2 == 10);
282 EXPECT_TRUE(value3 == 8);
283 }
284
285 } // namespace wificond
286 } // namespace android
287