C++程序  |  287行  |  8.8 KB

/*
 * 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 <linux/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, 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;
  uint32_t value2;
  uint8_t value3;
  EXPECT_TRUE(nested_attrs[0].GetAttributeValue(1, &value1));
  EXPECT_TRUE(nested_attrs[1].GetAttributeValue(1, &value2));
  EXPECT_TRUE(nested_attrs[2].GetAttributeValue(1, &value3));
  EXPECT_TRUE(value1 == 5);
  EXPECT_TRUE(value2 == 10);
  EXPECT_TRUE(value3 == 8);
}

}  // namespace wificond
}  // namespace android