Home | History | Annotate | Download | only in tests
      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 "wificond/net/kernel-header-latest/nl80211.h"
     22 #include "wificond/net/nl80211_attribute.h"
     23 #include "wificond/net/nl80211_packet.h"
     24 
     25 using std::string;
     26 
     27 namespace android {
     28 namespace wificond {
     29 
     30 namespace {
     31 
     32 const uint8_t kU8Value1 = 150;
     33 const uint16_t kU16Value1 = 5000;
     34 const uint32_t kU32Value1 = 500000;
     35 const uint32_t kU32Value2 = 800000;
     36 const uint32_t kPortId = 123;
     37 
     38 const uint8_t kGenNLCommand = 102;
     39 const uint16_t kNLMsgType = 4000;
     40 const uint32_t kNLMsgSequenceNumber = 70000;
     41 
     42 // NL80211 family id is dynamically allocated by kernel.
     43 const uint16_t kNL80211FamilyId = 0x13;
     44 const uint32_t kWiPhy = 0;
     45 const uint32_t kExpectedIfIndex = 4;
     46 const uint8_t kMacAddressBytes[] = {
     47     0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f
     48 };
     49 
     50 const unsigned char kNL80211_CMD_ASSOCIATE[] = {
     51     0x58, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
     52     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     53     0x26, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
     54     0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
     55     0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x33, 0x00,
     56     0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
     57     0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
     58     0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07,
     59     0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08,
     60     0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24,
     61     0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, 0x00, 0x00,
     62 };
     63 
     64 const uint32_t kExpectedCqmNotAcked = 50;
     65 
     66 const unsigned char kNL80211_CMD_NOTIFY_CQM[] = {
     67     0x3c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
     68     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     69     0x40, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
     70     0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
     71     0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
     72     0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
     73     0x0c, 0x00, 0x5e, 0x00, 0x08, 0x00, 0x04, 0x00,
     74     0x32, 0x00, 0x00, 0x00,
     75 };
     76 
     77 const uint32_t kNewStationExpectedGeneration = 275;
     78 
     79 const unsigned char kNL80211_CMD_NEW_STATION[] = {
     80     0x34, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
     81     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     82     0x13, 0x01, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
     83     0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
     84     0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
     85     0x08, 0x00, 0x2e, 0x00, 0x13, 0x01, 0x00, 0x00,
     86     0x04, 0x00, 0x15, 0x00,
     87 };
     88 
     89 }  // namespace
     90 
     91 TEST(NL80211PacketTest, CanConstructValidNL80211Packet) {
     92   NL80211Packet netlink_packet(kNLMsgType,
     93                                kGenNLCommand,
     94                                kNLMsgSequenceNumber,
     95                                kPortId);
     96   EXPECT_TRUE(netlink_packet.IsValid());
     97 }
     98 
     99 TEST(NL80211PacketTest, SetAndGetNL80211PacketHeaderFields) {
    100   NL80211Packet netlink_packet(kNLMsgType,
    101                                kGenNLCommand,
    102                                kNLMsgSequenceNumber,
    103                                kPortId);
    104   netlink_packet.SetFlags(NLM_F_MULTI);
    105   EXPECT_EQ(kGenNLCommand, netlink_packet.GetCommand());
    106   EXPECT_EQ(kNLMsgType, netlink_packet.GetMessageType());
    107   EXPECT_EQ(kNLMsgSequenceNumber, netlink_packet.GetMessageSequence());
    108   EXPECT_TRUE(netlink_packet.IsMulti());
    109   EXPECT_EQ(kPortId, netlink_packet.GetPortId());
    110 }
    111 
    112 TEST(NL80211PacketTest, AddAttributeToNL80211Packet) {
    113   NL80211Packet netlink_packet(kNLMsgType,
    114                                kGenNLCommand,
    115                                kNLMsgSequenceNumber,
    116                                kPortId);
    117   NL80211Attr<uint8_t> u8_attr(1, kU8Value1);
    118   netlink_packet.AddAttribute(u8_attr);
    119   EXPECT_TRUE(netlink_packet.IsValid());
    120   EXPECT_TRUE(netlink_packet.HasAttribute(1));
    121   uint8_t attr_value;
    122   EXPECT_TRUE(netlink_packet.GetAttributeValue(1, &attr_value));
    123   EXPECT_EQ(attr_value, kU8Value1);
    124 }
    125 
    126 TEST(NL80211PacketTest, AddMultipleAttributesToNL80211Packet) {
    127   NL80211Packet netlink_packet(kNLMsgType,
    128                                kGenNLCommand,
    129                                kNLMsgSequenceNumber,
    130                                kPortId);
    131   NL80211Attr<uint8_t> u8_attr(1, kU8Value1);
    132   NL80211Attr<uint32_t> u32_attr(2, kU32Value1);
    133   NL80211Attr<uint16_t> u16_attr(3, kU16Value1);
    134   netlink_packet.AddAttribute(u8_attr);
    135   netlink_packet.AddAttribute(u32_attr);
    136   netlink_packet.AddAttribute(u16_attr);
    137   EXPECT_TRUE(netlink_packet.IsValid());
    138   EXPECT_TRUE(netlink_packet.HasAttribute(1));
    139   EXPECT_TRUE(netlink_packet.HasAttribute(2));
    140   EXPECT_TRUE(netlink_packet.HasAttribute(3));
    141   uint8_t u8_attr_value;
    142   uint32_t u32_attr_value;
    143   uint16_t u16_attr_value;
    144   EXPECT_TRUE(netlink_packet.GetAttributeValue(1, &u8_attr_value));
    145   EXPECT_TRUE(netlink_packet.GetAttributeValue(2, &u32_attr_value));
    146   EXPECT_TRUE(netlink_packet.GetAttributeValue(3, &u16_attr_value));
    147   EXPECT_EQ(u8_attr_value, kU8Value1);
    148   EXPECT_EQ(u32_attr_value, kU32Value1);
    149   EXPECT_EQ(u16_attr_value, kU16Value1);
    150 }
    151 
    152 TEST(NL80211PacketTest, AddNestedAttributesToNL80211Packet) {
    153   NL80211Packet netlink_packet(kNLMsgType,
    154                                kGenNLCommand,
    155                                kNLMsgSequenceNumber,
    156                                kPortId);
    157   NL80211NestedAttr nested_attr(1);
    158   NL80211Attr<uint16_t> u16_attr(2, kU16Value1);
    159   NL80211Attr<uint32_t> u32_attr_1(3, kU32Value1);
    160   NL80211Attr<uint32_t> u32_attr_2(4, kU32Value2);
    161   nested_attr.AddAttribute(u16_attr);
    162   nested_attr.AddAttribute(u32_attr_1);
    163   netlink_packet.AddAttribute(nested_attr);
    164   netlink_packet.AddAttribute(u32_attr_2);
    165   EXPECT_TRUE(netlink_packet.HasAttribute(1));
    166   EXPECT_TRUE(netlink_packet.HasAttribute(4));
    167   // Attribute 2 and 3 are deeper nested.
    168   // They should not be found from packet level.
    169   EXPECT_FALSE(netlink_packet.HasAttribute(2));
    170   EXPECT_FALSE(netlink_packet.HasAttribute(3));
    171 }
    172 
    173 TEST(NL80211PacketTest, CannotGetMissingAttributeFromNL80211Packet) {
    174   NL80211Packet netlink_packet(kNLMsgType,
    175                                kGenNLCommand,
    176                                kNLMsgSequenceNumber,
    177                                kPortId);
    178   NL80211Attr<uint8_t> u8_attr(1, kU8Value1);
    179   netlink_packet.AddAttribute(u8_attr);
    180   EXPECT_TRUE(netlink_packet.IsValid());
    181   EXPECT_FALSE(netlink_packet.HasAttribute(2));
    182   uint8_t attr_value;
    183   EXPECT_FALSE(netlink_packet.GetAttributeValue(2, &attr_value));
    184 }
    185 
    186 TEST(NL80211PacketTest, CanGetAllOfAttributeFromNL80211Packet) {
    187   NL80211Packet netlink_packet(kNLMsgType,
    188                                kGenNLCommand,
    189                                kNLMsgSequenceNumber,
    190                                kPortId);
    191   NL80211Attr<uint8_t> u8_attr(1, kU8Value1);
    192   NL80211Attr<uint32_t> u32_attr_1(2, kU32Value1);
    193   NL80211Attr<uint32_t> u32_attr_2(4, kU32Value2);
    194   netlink_packet.AddAttribute(u8_attr);
    195   netlink_packet.AddAttribute(u32_attr_1);
    196   netlink_packet.AddAttribute(u32_attr_2);
    197   EXPECT_TRUE(netlink_packet.IsValid());
    198   std::vector<BaseNL80211Attr> attributes;
    199   EXPECT_TRUE(netlink_packet.GetAllAttributes(&attributes));
    200 
    201   EXPECT_TRUE(attributes.size() == 3);
    202 
    203   NL80211Attr<uint8_t>* u8_attr_retrieved =
    204       static_cast<NL80211Attr<uint8_t>*>(&attributes[0]);
    205   EXPECT_TRUE(u8_attr_retrieved->GetValue() == kU8Value1);
    206 
    207   NL80211Attr<uint32_t>* u32_attr_1_retrieved =
    208       static_cast<NL80211Attr<uint32_t>*>(&attributes[1]);
    209   EXPECT_TRUE(u32_attr_1_retrieved->GetValue() == kU32Value1);
    210 
    211   NL80211Attr<uint32_t>* u32_attr_2_retrieved =
    212       static_cast<NL80211Attr<uint32_t>*>(&attributes[2]);
    213   EXPECT_TRUE(u32_attr_2_retrieved->GetValue() == kU32Value2);
    214 }
    215 
    216 TEST(NL80211PacketTest, ParseCMDAssociateTest) {
    217   NL80211Packet netlink_packet(std::vector<uint8_t>(
    218       kNL80211_CMD_ASSOCIATE,
    219       kNL80211_CMD_ASSOCIATE + sizeof(kNL80211_CMD_ASSOCIATE)));
    220   EXPECT_TRUE(netlink_packet.IsValid());
    221   EXPECT_EQ(kNL80211FamilyId, netlink_packet.GetMessageType());
    222   EXPECT_EQ(NL80211_CMD_ASSOCIATE, netlink_packet.GetCommand());
    223   uint32_t value;
    224   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_WIPHY, &value));
    225   EXPECT_EQ(kWiPhy, value);
    226   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_IFINDEX, &value));
    227   EXPECT_EQ(kExpectedIfIndex, value);
    228   std::vector<uint8_t> rawdata;
    229   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_FRAME, &rawdata));
    230   EXPECT_FALSE(rawdata.empty());
    231 
    232 }
    233 
    234 TEST(NL80211PacketTest, ParseCMDNotifyCQMTest) {
    235   NL80211Packet netlink_packet(std::vector<uint8_t>(
    236       kNL80211_CMD_NOTIFY_CQM,
    237       kNL80211_CMD_NOTIFY_CQM + sizeof(kNL80211_CMD_NOTIFY_CQM)));
    238   EXPECT_TRUE(netlink_packet.IsValid());
    239   EXPECT_EQ(kNL80211FamilyId, netlink_packet.GetMessageType());
    240   EXPECT_EQ(NL80211_CMD_NOTIFY_CQM, netlink_packet.GetCommand());
    241   uint32_t value;
    242   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_WIPHY, &value));
    243   EXPECT_EQ(kWiPhy, value);
    244   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_IFINDEX, &value));
    245   EXPECT_EQ(kExpectedIfIndex, value);
    246   std::vector<uint8_t> mac;
    247   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_MAC, &mac));
    248   std::vector<uint8_t> expected_mac(
    249       kMacAddressBytes,
    250       kMacAddressBytes + sizeof(kMacAddressBytes));
    251   EXPECT_EQ(expected_mac, mac);
    252   NL80211NestedAttr nested(0);
    253   EXPECT_TRUE(netlink_packet.GetAttribute(NL80211_ATTR_CQM, &nested));
    254   EXPECT_TRUE(nested.GetAttributeValue(NL80211_ATTR_CQM_PKT_LOSS_EVENT, &value));
    255   EXPECT_EQ(kExpectedCqmNotAcked, value);
    256 }
    257 
    258 TEST(NL80211PacketTest, ParseCMDNewStation) {
    259   NL80211Packet netlink_packet(std::vector<uint8_t>(
    260       kNL80211_CMD_NEW_STATION,
    261       kNL80211_CMD_NEW_STATION + sizeof(kNL80211_CMD_NEW_STATION)));
    262   EXPECT_TRUE(netlink_packet.IsValid());
    263   EXPECT_EQ(kNL80211FamilyId, netlink_packet.GetMessageType());
    264   EXPECT_EQ(NL80211_CMD_NEW_STATION, netlink_packet.GetCommand());
    265   uint32_t value;
    266   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_IFINDEX, &value));
    267   EXPECT_EQ(kExpectedIfIndex, value);
    268   std::vector<uint8_t> mac;
    269   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_MAC, &mac));
    270   std::vector<uint8_t> expected_mac(
    271       kMacAddressBytes,
    272       kMacAddressBytes + sizeof(kMacAddressBytes));
    273   EXPECT_EQ(expected_mac, mac);
    274   NL80211NestedAttr nested(0);
    275   EXPECT_TRUE(netlink_packet.GetAttribute(NL80211_ATTR_STA_INFO, &nested));
    276   EXPECT_TRUE(netlink_packet.GetAttributeValue(NL80211_ATTR_GENERATION,
    277                                                &value));
    278   EXPECT_EQ(kNewStationExpectedGeneration, value);
    279 }
    280 
    281 }  // namespace wificond
    282 }  // namespace android
    283