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