343 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			343 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2016, The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *     http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #include <memory>
 | |
| 
 | |
| #include <gtest/gtest.h>
 | |
| 
 | |
| #include "wificond/net/kernel-header-latest/nl80211.h"
 | |
| #include "wificond/net/nl80211_attribute.h"
 | |
| 
 | |
| namespace android {
 | |
| namespace wificond {
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| const uint32_t kU8Value1 = 200;
 | |
| const uint32_t kU16Value1 = 5000;
 | |
| const uint32_t kU32Value1 = 250000;
 | |
| const uint32_t kU32Value2 = 500000;
 | |
| const std::string kIFName = "wlan0";
 | |
| const uint8_t kMacAddress[] = {
 | |
|     0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f
 | |
| };
 | |
| 
 | |
| // This header contains invalid buffer length
 | |
| const uint8_t kBrokenBuffer[] = {
 | |
|     0xff, 0xff, // nla_len = 0xffff
 | |
|     0x01, 0x11, // nla_type
 | |
|     0x15, 0x12, // payload
 | |
|     0x00, 0x00  // padding
 | |
| };
 | |
| const uint8_t kValidU32AttrBuffer[] = {
 | |
|     0x08, 0x00, // nla_len = 8
 | |
|     0x01, 0x00, // nla_type
 | |
|     0xf1, 0x12, 0x12, 0x2a // payload
 | |
| };
 | |
| const uint8_t kBufferContainsStringWithTrailingZero[] = {
 | |
|     0x0a, 0x00, // nla_len = 10
 | |
|     0x01, 0x00, // nla_type
 | |
|     'w', 'l', 'a', 'n', '0', '\0',
 | |
|     0x00, 0x00  // padding
 | |
| };
 | |
| const uint8_t kBufferContainsStringWithTrailingZeros[] = {
 | |
|     0x0c, 0x00, // nla_len = 12
 | |
|     0x01, 0x00, // nla_type
 | |
|     'w', 'l', 'a', 'n', '0', '\0', '\0', '\0'
 | |
| };
 | |
| const uint8_t kBufferContainsStringWithoutTrailingZero[] = {
 | |
|     0x09, 0x00, // nla_len = 9
 | |
|     0x01, 0x00, // nla_type
 | |
|     'w', 'l', 'a', 'n', '0',
 | |
|     0x00, 0x00, 0x00  // padding
 | |
| };
 | |
| 
 | |
| const uint8_t kBufferContainsListOfAttributes[] = {
 | |
|     0x28, 0x00, // nla_len = 40
 | |
|     0x01, 0x00, // nla_type
 | |
|     // List of attributes:
 | |
|     // They have attribute id from 0 to N.
 | |
|     0x0a, 0x00, // nla_len = 10
 | |
|     0x00, 0x00, // nla_type = 0
 | |
|     'f', 'i', 'r', 's', 't','\0',
 | |
|     0x00, 0x00,  // padding
 | |
|     0x0b, 0x00, // nla_len = 11
 | |
|     0x01, 0x00, // nla_type = 1
 | |
|     's', 'e', 'c', 'o', 'n', 'd','\0',
 | |
|     0x00, // padding
 | |
|     0x0a, 0x00, // nla_len = 10
 | |
|     0x02, 0x00, // nla_type = 2
 | |
|     't', 'h', 'i', 'r', 'd','\0',
 | |
|     0x00, 0x00, // padding
 | |
| };
 | |
| 
 | |
| const uint8_t kBufferContainsListOfNestedAttributes[] = {
 | |
|     0x28, 0x00, // nla_len = 40
 | |
|     0x01, 0x00, // nla_type
 | |
| 
 | |
|     // List of nested attributes:
 | |
|     // They have attribute id from 0 to N.
 | |
| 
 | |
|     // Nested attribute 1:
 | |
|     0x0c, 0x00, // nla_len = 12
 | |
|     0x00, 0x00, // nla_type = 0
 | |
|         0x06, 0x00, // nla_len = 6
 | |
|         0x01, 0x00, // nla_type
 | |
|         0x05, 0x00, // uint16_t attribute with value 5
 | |
|         0x00, 0x00, // padding
 | |
| 
 | |
|     // Nested attribute 2:
 | |
|     0x0c, 0x00, // nla_len = 12
 | |
|     0x01, 0x00, // nla_type = 1
 | |
|         0x08, 0x00, // nla_len = 8
 | |
|         0x01, 0x00, // nla_type
 | |
|         0x0a, 0x00,
 | |
|         0x00, 0x00, // uint32_t attribute with value 10
 | |
| 
 | |
|     // Nested attribute 3:
 | |
|     0x0c, 0x00, // nla_len = 12
 | |
|     0x02, 0x00, // nla_type = 2
 | |
|         0x05, 0x00, // nla_len = 5
 | |
|         0x01, 0x00, // nla_type
 | |
|         0x08, 0x00, // uint8_t attribute with value 8
 | |
|         0x00, 0x00, // padding
 | |
| };
 | |
| 
 | |
| }  // namespace
 | |
| 
 | |
| TEST(NL80211AttributeTest,U8AttributesSeriallizeCorrectly) {
 | |
|   NL80211Attr<uint8_t> u8_attr(1, kU8Value1);
 | |
|   EXPECT_EQ(u8_attr.GetValue(), kU8Value1);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest,U16AttributesSeriallizeCorrectly) {
 | |
|   NL80211Attr<uint16_t> u16_attr(1, kU16Value1);
 | |
|   EXPECT_EQ(u16_attr.GetValue(), kU16Value1);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest,U32AttributesSeriallizeCorrectly) {
 | |
|   NL80211Attr<uint32_t> u32_attr(1, kU32Value1);
 | |
|   EXPECT_EQ(u32_attr.GetValue(), kU32Value1);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest,StringAttributesSeriallizeCorrectly) {
 | |
|   NL80211Attr<std::string> str_attr(1, kIFName);
 | |
|   EXPECT_EQ(str_attr.GetValue(), kIFName);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, ByteVectorsSeriallizeCorrectly) {
 | |
|   std::vector<uint8_t> mac_address(
 | |
|       kMacAddress,
 | |
|       kMacAddress + sizeof(kMacAddress));
 | |
|   NL80211Attr<std::vector<uint8_t>> byte_vector_attr(1, mac_address);
 | |
|   EXPECT_EQ(byte_vector_attr.GetValue(), mac_address);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, CanGetNestedAttributes) {
 | |
|   NL80211NestedAttr nested_attr(1);
 | |
|   NL80211Attr<uint32_t> u32_attr_1(1, kU32Value1);
 | |
|   NL80211Attr<uint32_t> u32_attr_2(2, kU32Value2);
 | |
| 
 | |
|   nested_attr.AddAttribute(u32_attr_1);
 | |
|   nested_attr.AddAttribute(u32_attr_2);
 | |
| 
 | |
|   EXPECT_TRUE(nested_attr.HasAttribute(1));
 | |
|   EXPECT_TRUE(nested_attr.HasAttribute(2));
 | |
| 
 | |
|   uint32_t attr_value;
 | |
|   EXPECT_TRUE(nested_attr.GetAttributeValue(1, &attr_value));
 | |
|   EXPECT_EQ(attr_value, kU32Value1);
 | |
|   EXPECT_TRUE(nested_attr.GetAttributeValue(2, &attr_value));
 | |
|   EXPECT_EQ(attr_value, kU32Value2);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, CannotGetDoubleNestedAttributes) {
 | |
|   NL80211NestedAttr nested_attr(1);
 | |
|   NL80211NestedAttr deeper_nested_attr(2);
 | |
|   NL80211Attr<uint32_t> u32_attr_1(3, kU32Value1);
 | |
| 
 | |
|   deeper_nested_attr.AddAttribute(u32_attr_1);
 | |
|   nested_attr.AddAttribute(deeper_nested_attr);
 | |
| 
 | |
|   EXPECT_FALSE(nested_attr.HasAttribute(3));
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, CannotGetMissingAttribute) {
 | |
|   NL80211NestedAttr nested_attr(1);
 | |
|   NL80211Attr<uint32_t> u32_attr_1(1, kU32Value1);
 | |
| 
 | |
|   nested_attr.AddAttribute(u32_attr_1);
 | |
| 
 | |
|   uint32_t attr_value;
 | |
|   EXPECT_FALSE(nested_attr.HasAttribute(2));
 | |
|   EXPECT_FALSE(nested_attr.GetAttributeValue(2, &attr_value));
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, CannotGetAttributeWithWrongType) {
 | |
|   NL80211NestedAttr nested_attr(1);
 | |
|   NL80211Attr<uint32_t> u32_attr_1(1, kU32Value1);
 | |
| 
 | |
|   nested_attr.AddAttribute(u32_attr_1);
 | |
| 
 | |
|   uint16_t attr_value;
 | |
|   EXPECT_TRUE(nested_attr.HasAttribute(1));
 | |
|   EXPECT_FALSE(nested_attr.GetAttributeValue(1, &attr_value));
 | |
| }
 | |
| 
 | |
| 
 | |
| TEST(NL80211AttributeTest, InvalidU32AttributeWithEmptyBuffer) {
 | |
|   std::vector<uint8_t> buffer;
 | |
|   NL80211Attr<uint32_t> invalid_attr(buffer);
 | |
|   EXPECT_FALSE(invalid_attr.IsValid());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, InvalidU32AttributeWithBrokenBuffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kBrokenBuffer,
 | |
|       kBrokenBuffer + sizeof(kBrokenBuffer));
 | |
|   NL80211Attr<uint32_t> invalid_attr(buffer);
 | |
|   EXPECT_FALSE(invalid_attr.IsValid());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, InvalidU16AttributeWithU32Buffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kValidU32AttrBuffer,
 | |
|       kValidU32AttrBuffer + sizeof(kValidU32AttrBuffer));
 | |
|   NL80211Attr<uint32_t> valid_attr(buffer);
 | |
|   NL80211Attr<uint16_t> invalid_attr(buffer);
 | |
|   EXPECT_TRUE(valid_attr.IsValid());
 | |
|   EXPECT_FALSE(invalid_attr.IsValid());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, InitStringAttributeWithTrailingZeroFromBuffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kBufferContainsStringWithTrailingZero,
 | |
|       kBufferContainsStringWithTrailingZero +
 | |
|           sizeof(kBufferContainsStringWithTrailingZero));
 | |
|   NL80211Attr<std::string> str_attr(buffer);
 | |
|   EXPECT_EQ("wlan0", str_attr.GetValue());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, InitStringAttributeWithTrailingZerosFromBuffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kBufferContainsStringWithTrailingZeros,
 | |
|       kBufferContainsStringWithTrailingZeros +
 | |
|           sizeof(kBufferContainsStringWithTrailingZeros));
 | |
|   NL80211Attr<std::string> str_attr(buffer);
 | |
|   EXPECT_EQ("wlan0", str_attr.GetValue());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, InitStringAttributeWithoutTrailingZeroFromBuffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kBufferContainsStringWithoutTrailingZero,
 | |
|       kBufferContainsStringWithoutTrailingZero +
 | |
|           sizeof(kBufferContainsStringWithoutTrailingZero));
 | |
|   NL80211Attr<std::string> str_attr(buffer);
 | |
|   EXPECT_EQ("wlan0", str_attr.GetValue());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, GetListOfStringsFromBuffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kBufferContainsListOfAttributes,
 | |
|       kBufferContainsListOfAttributes +
 | |
|           sizeof(kBufferContainsListOfAttributes));
 | |
|   std::vector<std::string> strs;
 | |
|   std::vector<std::string> expected_strs = {"first", "second", "third"};
 | |
|   NL80211NestedAttr nested_attr(buffer);
 | |
|   nested_attr.GetListOfAttributeValues(&strs);
 | |
|   EXPECT_EQ(expected_strs, strs);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, GetListOfAttributesFromBuffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kBufferContainsListOfAttributes,
 | |
|       kBufferContainsListOfAttributes +
 | |
|           sizeof(kBufferContainsListOfAttributes));
 | |
| 
 | |
|   std::vector<NL80211Attr<std::string>> attrs;
 | |
|   NL80211NestedAttr attr(buffer);
 | |
|   EXPECT_TRUE(attr.GetListOfAttributes(&attrs));
 | |
|   EXPECT_TRUE(attrs.size() == 3);
 | |
|   ASSERT_EQ(0, attrs[0].GetAttributeId());
 | |
|   ASSERT_EQ(1, attrs[1].GetAttributeId());
 | |
|   ASSERT_EQ(2, attrs[2].GetAttributeId());
 | |
|   ASSERT_EQ("first", attrs[0].GetValue());
 | |
|   ASSERT_EQ("second", attrs[1].GetValue());
 | |
|   ASSERT_EQ("third", attrs[2].GetValue());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, GetListOfNestedAttributesFromBuffer) {
 | |
|   std::vector<uint8_t> buffer(
 | |
|       kBufferContainsListOfNestedAttributes,
 | |
|       kBufferContainsListOfNestedAttributes +
 | |
|           sizeof(kBufferContainsListOfNestedAttributes));
 | |
|   std::vector<NL80211NestedAttr> nested_attrs;
 | |
|   NL80211NestedAttr attr(buffer);
 | |
|   EXPECT_TRUE(attr.GetListOfNestedAttributes(&nested_attrs));
 | |
|   EXPECT_TRUE(nested_attrs.size() == 3);
 | |
|   uint16_t value1 = 0;
 | |
|   uint32_t value2 = 0;
 | |
|   uint8_t value3 = 0;
 | |
|   ASSERT_TRUE(nested_attrs[0].GetAttributeValue(1, &value1));
 | |
|   ASSERT_TRUE(nested_attrs[1].GetAttributeValue(1, &value2));
 | |
|   ASSERT_TRUE(nested_attrs[2].GetAttributeValue(1, &value3));
 | |
|   EXPECT_TRUE(value1 == 5);
 | |
|   EXPECT_TRUE(value2 == 10);
 | |
|   EXPECT_TRUE(value3 == 8);
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, MergeAttributes) {
 | |
|   NL80211Attr<std::vector<uint8_t>> attr1(1, {'a', 'b', 'c'});
 | |
|   NL80211Attr<std::vector<uint8_t>> attr2(1, {'d', 'e'});
 | |
|   ASSERT_TRUE(attr1.Merge(attr2));
 | |
|   std::vector<uint8_t> expected_value{{'a', 'b', 'c', 'd', 'e'}};
 | |
|   EXPECT_EQ(expected_value, attr1.GetValue());
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, CannotMergeInvalidAttributeWithBrokenBuffer) {
 | |
|   NL80211Attr<std::vector<uint8_t>> valid_attr(1, {'a', 'b', 'c'});
 | |
|   std::vector<uint8_t> broken_buffer(
 | |
|       kBrokenBuffer,
 | |
|       kBrokenBuffer + sizeof(kBrokenBuffer));
 | |
|   NL80211Attr<std::vector<uint8_t>> invalid_attr(broken_buffer);
 | |
|   EXPECT_FALSE(valid_attr.Merge(invalid_attr));
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, CannotMergeAttributesWithDifferentIds) {
 | |
|   NL80211Attr<std::vector<uint8_t>> attr1(1, {'a', 'b', 'c'});
 | |
|   NL80211Attr<std::vector<uint8_t>> attr2(2, {'d', 'e', 'f'});
 | |
|   EXPECT_FALSE(attr1.Merge(attr2));
 | |
| }
 | |
| 
 | |
| TEST(NL80211AttributeTest, MergeNestedAttributes) {
 | |
|   NL80211NestedAttr nested_attr1(0);
 | |
|   NL80211NestedAttr nested_attr2(0);
 | |
|   NL80211Attr<uint32_t> uint32_attr1(1, kU32Value1);
 | |
|   NL80211Attr<uint32_t> uint32_attr2(2, kU32Value2);
 | |
|   nested_attr1.AddAttribute(uint32_attr1);
 | |
|   nested_attr2.AddAttribute(uint32_attr2);
 | |
|   ASSERT_TRUE(nested_attr1.Merge(nested_attr2));
 | |
| 
 | |
|   uint32_t value1, value2;
 | |
|   EXPECT_TRUE(nested_attr1.GetAttributeValue(1, &value1));
 | |
|   EXPECT_TRUE(value1 == kU32Value1);
 | |
|   EXPECT_TRUE(nested_attr1.GetAttributeValue(2, &value2));
 | |
|   EXPECT_TRUE(value2 == kU32Value2);
 | |
| }
 | |
| 
 | |
| }  // namespace wificond
 | |
| }  // namespace android
 |