Home | History | Annotate | Download | only in net
      1 //
      2 // Copyright (C) 2013 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 // This file provides tests for individual messages.  It tests
     18 // NetlinkMessageFactory's ability to create specific message types and it
     19 // tests the various NetlinkMessage types' ability to parse those
     20 // messages.
     21 
     22 // This file tests the public interface to NetlinkMessage.
     23 
     24 #include "shill/net/nl80211_message.h"
     25 
     26 #include <memory>
     27 #include <string>
     28 #include <vector>
     29 
     30 #include <base/strings/stringprintf.h>
     31 #include <gmock/gmock.h>
     32 #include <gtest/gtest.h>
     33 
     34 #include "shill/net/mock_netlink_socket.h"
     35 #include "shill/net/netlink_attribute.h"
     36 #include "shill/net/netlink_packet.h"
     37 
     38 using base::Bind;
     39 using base::StringPrintf;
     40 using base::Unretained;
     41 using std::string;
     42 using std::unique_ptr;
     43 using std::vector;
     44 using testing::_;
     45 using testing::EndsWith;
     46 using testing::Invoke;
     47 using testing::Return;
     48 using testing::Test;
     49 
     50 namespace shill {
     51 
     52 namespace {
     53 
     54 // These data blocks have been collected by shill using NetlinkManager while,
     55 // simultaneously (and manually) comparing shill output with that of the 'iw'
     56 // code from which it was derived.  The test strings represent the raw packet
     57 // data coming from the kernel.  The comments above each of these strings is
     58 // the markup that 'iw' outputs for each of these packets.
     59 
     60 // These constants are consistent throughout the packets, below.
     61 
     62 const uint32_t kExpectedIfIndex = 4;
     63 const uint32_t kWiPhy = 0;
     64 const uint16_t kNl80211FamilyId = 0x13;
     65 const char kExpectedMacAddress[] = "c0:3f:0e:77:e8:7f";
     66 
     67 const uint8_t kMacAddressBytes[] = {
     68   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f
     69 };
     70 
     71 const uint8_t kRespIeBytes[] = {
     72   0x01, 0x08, 0x82, 0x84,
     73   0x8b, 0x96, 0x0c, 0x12,
     74   0x18, 0x24, 0x32, 0x04,
     75   0x30, 0x48, 0x60, 0x6c
     76 };
     77 
     78 
     79 // wlan0 (phy #0): scan started
     80 
     81 const uint32_t kScanFrequencyTrigger[] = {
     82   2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
     83   2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200,
     84   5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520,
     85   5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
     86   5700, 5745, 5765, 5785, 5805, 5825
     87 };
     88 
     89 const unsigned char kNL80211_CMD_TRIGGER_SCAN[] = {
     90   0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
     91   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     92   0x21, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
     93   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
     94   0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00,
     95   0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00,
     96   0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00,
     97   0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00,
     98   0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00,
     99   0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00,
    100   0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00,
    101   0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00,
    102   0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00,
    103   0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00,
    104   0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00,
    105   0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00,
    106   0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00,
    107   0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00,
    108   0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00,
    109   0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00,
    110   0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00,
    111   0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00,
    112   0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00,
    113   0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00,
    114   0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00,
    115   0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00,
    116   0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00,
    117   0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00,
    118   0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00,
    119   0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00,
    120   0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00,
    121   0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00,
    122   0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00,
    123   0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00,
    124   0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00,
    125   0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00,
    126   0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00,
    127   0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00,
    128   0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00,
    129   0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00,
    130   0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00,
    131   0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00,
    132   0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00,
    133   0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00,
    134   0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
    135 };
    136 
    137 
    138 // wlan0 (phy #0): scan finished: 2412 2417 2422 2427 2432 2437 2442 2447 2452
    139 // 2457 2462 2467 2472 2484 5180 5200 5220 5240 5260 5280 5300 5320 5500 5520
    140 // 5540 5560 5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825, ""
    141 
    142 const uint32_t kScanFrequencyResults[] = {
    143   2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
    144   2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200,
    145   5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520,
    146   5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
    147   5700, 5745, 5765, 5785, 5805, 5825
    148 };
    149 
    150 const unsigned char kNL80211_CMD_NEW_SCAN_RESULTS[] = {
    151   0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    152   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    153   0x22, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    154   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    155   0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00,
    156   0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00,
    157   0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00,
    158   0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00,
    159   0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00,
    160   0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00,
    161   0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00,
    162   0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00,
    163   0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00,
    164   0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00,
    165   0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00,
    166   0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00,
    167   0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00,
    168   0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00,
    169   0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00,
    170   0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00,
    171   0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00,
    172   0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00,
    173   0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00,
    174   0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00,
    175   0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00,
    176   0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00,
    177   0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00,
    178   0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00,
    179   0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00,
    180   0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00,
    181   0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00,
    182   0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00,
    183   0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00,
    184   0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00,
    185   0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00,
    186   0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00,
    187   0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00,
    188   0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00,
    189   0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00,
    190   0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00,
    191   0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00,
    192   0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00,
    193   0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00,
    194   0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00,
    195   0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
    196 };
    197 
    198 
    199 // wlan0: new station c0:3f:0e:77:e8:7f
    200 
    201 const uint32_t kNewStationExpectedGeneration = 275;
    202 
    203 const unsigned char kNL80211_CMD_NEW_STATION[] = {
    204   0x34, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    205   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    206   0x13, 0x01, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    207   0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
    208   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
    209   0x08, 0x00, 0x2e, 0x00, 0x13, 0x01, 0x00, 0x00,
    210   0x04, 0x00, 0x15, 0x00,
    211 };
    212 
    213 
    214 // wlan0 (phy #0): auth c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0:
    215 // Successful [frame: b0 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0
    216 // 3f 0e 77 e8 7f 30 07 00 00 02 00 00 00]
    217 
    218 const unsigned char kAuthenticateFrame[] = {
    219   0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
    220   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
    221   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07,
    222   0x00, 0x00, 0x02, 0x00, 0x00, 0x00
    223 };
    224 
    225 const unsigned char kNL80211_CMD_AUTHENTICATE[] = {
    226   0x48, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    227   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    228   0x25, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    229   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    230   0x04, 0x00, 0x00, 0x00, 0x22, 0x00, 0x33, 0x00,
    231   0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
    232   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
    233   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07,
    234   0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
    235 };
    236 
    237 
    238 // wlan0 (phy #0): assoc c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0:
    239 // Successful [frame: 10 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0 3f 0e
    240 // 77 e8 7f 40 07 01 04 00 00 01 c0 01 08 82 84 8b 96 0c 12 18 24 32 04 30 48
    241 // 60 6c]
    242 
    243 const unsigned char kAssociateFrame[] = {
    244   0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
    245   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
    246   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07,
    247   0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08,
    248   0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24,
    249   0x32, 0x04, 0x30, 0x48, 0x60, 0x6c
    250 };
    251 
    252 const unsigned char kNL80211_CMD_ASSOCIATE[] = {
    253   0x58, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    254   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    255   0x26, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    256   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    257   0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x33, 0x00,
    258   0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
    259   0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
    260   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07,
    261   0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08,
    262   0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24,
    263   0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, 0x00, 0x00,
    264 };
    265 
    266 
    267 // wlan0 (phy #0): connected to c0:3f:0e:77:e8:7f
    268 
    269 const uint16_t kExpectedConnectStatus = 0;
    270 
    271 const unsigned char kNL80211_CMD_CONNECT[] = {
    272   0x4c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    273   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    274   0x2e, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    275   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    276   0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
    277   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
    278   0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
    279   0x14, 0x00, 0x4e, 0x00, 0x01, 0x08, 0x82, 0x84,
    280   0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x32, 0x04,
    281   0x30, 0x48, 0x60, 0x6c,
    282 };
    283 
    284 
    285 // wlan0 (phy #0): deauth c0:3f:0e:77:e8:7f -> ff:ff:ff:ff:ff:ff reason 2:
    286 // Previous authentication no longer valid [frame: c0 00 00 00 ff ff ff ff
    287 // ff ff c0 3f 0e 77 e8 7f c0 3f 0e 77 e8 7f c0 0e 02 00]
    288 
    289 const unsigned char kDeauthenticateFrame[] = {
    290   0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
    291   0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
    292   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
    293   0x02, 0x00
    294 };
    295 
    296 const unsigned char kNL80211_CMD_DEAUTHENTICATE[] = {
    297   0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    298   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    299   0x27, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    300   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    301   0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00,
    302   0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
    303   0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
    304   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
    305   0x02, 0x00, 0x00, 0x00,
    306 };
    307 
    308 
    309 // wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no
    310 // longer valid
    311 
    312 const uint16_t kExpectedDisconnectReason = 2;
    313 
    314 const unsigned char kNL80211_CMD_DISCONNECT[] = {
    315   0x30, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    316   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    317   0x30, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    318   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    319   0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x36, 0x00,
    320   0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x47, 0x00,
    321 };
    322 
    323 
    324 // wlan0 (phy #0): connection quality monitor event: peer c0:3f:0e:77:e8:7f
    325 // didn't ACK 50 packets
    326 
    327 const uint32_t kExpectedCqmNotAcked = 50;
    328 
    329 const unsigned char kNL80211_CMD_NOTIFY_CQM[] = {
    330   0x3c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    331   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    332   0x40, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    333   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    334   0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
    335   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
    336   0x0c, 0x00, 0x5e, 0x00, 0x08, 0x00, 0x04, 0x00,
    337   0x32, 0x00, 0x00, 0x00,
    338 };
    339 
    340 
    341 // wlan0 (phy #0): disassoc 48:5d:60:77:2d:cf -> c0:3f:0e:77:e8:7f reason 3:
    342 // Deauthenticated because sending station is  [frame: a0 00 00 00 c0 3f 0e
    343 // 77 e8 7f 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f 00 00 03 00]
    344 
    345 const unsigned char kDisassociateFrame[] = {
    346   0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77,
    347   0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf,
    348   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
    349   0x03, 0x00
    350 };
    351 
    352 const unsigned char kNL80211_CMD_DISASSOCIATE[] = {
    353   0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    354   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    355   0x28, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    356   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    357   0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00,
    358   0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77,
    359   0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf,
    360   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
    361   0x03, 0x00, 0x00, 0x00,
    362 };
    363 
    364 // This is just a NL80211_CMD_NEW_STATION message with the command changed to
    365 // 0xfe (which is, intentionally, not a supported command).
    366 
    367 const unsigned char kCmdNL80211_CMD_UNKNOWN = 0xfe;
    368 const unsigned char kNL80211_CMD_UNKNOWN[] = {
    369   0x34, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
    370   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    371   0xfe, 0x01, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
    372   0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
    373   0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
    374   0x08, 0x00, 0x2e, 0x00, 0x13, 0x01, 0x00, 0x00,
    375   0x04, 0x00, 0x15, 0x00,
    376 };
    377 
    378 }  // namespace
    379 
    380 class NetlinkMessageTest : public Test {
    381  public:
    382   NetlinkMessageTest() {
    383     message_factory_.AddFactoryMethod(
    384         kNl80211FamilyId, Bind(&Nl80211Message::CreateMessage));
    385     Nl80211Message::SetMessageType(kNl80211FamilyId);
    386   }
    387 
    388  protected:
    389   // Helper function to provide an array of scan frequencies from a message's
    390   // NL80211_ATTR_SCAN_FREQUENCIES attribute.
    391   static bool GetScanFrequenciesFromMessage(const Nl80211Message& message,
    392                                             vector<uint32_t>* value) {
    393     if (!value) {
    394       LOG(ERROR) << "Null |value| parameter";
    395       return false;
    396     }
    397 
    398     AttributeListConstRefPtr frequency_list;
    399     if (!message.const_attributes()->ConstGetNestedAttributeList(
    400         NL80211_ATTR_SCAN_FREQUENCIES, &frequency_list) || !frequency_list) {
    401       LOG(ERROR) << "Couldn't get NL80211_ATTR_SCAN_FREQUENCIES attribute";
    402       return false;
    403     }
    404 
    405     AttributeIdIterator freq_iter(*frequency_list);
    406     value->clear();
    407     for (; !freq_iter.AtEnd(); freq_iter.Advance()) {
    408       uint32_t freq = 0;
    409       if (frequency_list->GetU32AttributeValue(freq_iter.GetId(), &freq)) {
    410         value->push_back(freq);
    411       }
    412     }
    413     return true;
    414   }
    415 
    416   // Helper function to provide an array of SSIDs from a message's
    417   // NL80211_ATTR_SCAN_SSIDS attribute.
    418   static bool GetScanSsidsFromMessage(const Nl80211Message& message,
    419                                       vector<string>* value) {
    420     if (!value) {
    421       LOG(ERROR) << "Null |value| parameter";
    422       return false;
    423     }
    424 
    425     AttributeListConstRefPtr ssid_list;
    426     if (!message.const_attributes()->ConstGetNestedAttributeList(
    427         NL80211_ATTR_SCAN_SSIDS, &ssid_list) || !ssid_list) {
    428       LOG(ERROR) << "Couldn't get NL80211_ATTR_SCAN_SSIDS attribute";
    429       return false;
    430     }
    431 
    432     AttributeIdIterator ssid_iter(*ssid_list);
    433     value->clear();
    434     for (; !ssid_iter.AtEnd(); ssid_iter.Advance()) {
    435       string ssid;
    436       if (ssid_list->GetStringAttributeValue(ssid_iter.GetId(), &ssid)) {
    437         value->push_back(ssid);
    438       }
    439     }
    440     return true;
    441   }
    442 
    443   NetlinkMessageFactory message_factory_;
    444 };
    445 
    446 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_TRIGGER_SCAN) {
    447   NetlinkPacket trigger_scan_packet(
    448       kNL80211_CMD_TRIGGER_SCAN, sizeof(kNL80211_CMD_TRIGGER_SCAN));
    449   unique_ptr<NetlinkMessage> netlink_message(
    450       message_factory_.CreateMessage(
    451           &trigger_scan_packet, NetlinkMessage::MessageContext()));
    452 
    453   EXPECT_NE(nullptr, netlink_message);
    454   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    455   // The following is legal if the message_type is kNl80211FamilyId.
    456   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    457       netlink_message.release()));
    458 
    459   EXPECT_EQ(NL80211_CMD_TRIGGER_SCAN, message->command());
    460 
    461   {
    462     uint32_t value;
    463     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    464         NL80211_ATTR_WIPHY, &value));
    465     EXPECT_EQ(kWiPhy, value);
    466   }
    467 
    468   {
    469     uint32_t value;
    470     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    471         NL80211_ATTR_IFINDEX, &value));
    472     EXPECT_EQ(kExpectedIfIndex, value);
    473   }
    474 
    475   // Make sure the scan frequencies in the attribute are the ones we expect.
    476   {
    477     vector<uint32_t>list;
    478     EXPECT_TRUE(GetScanFrequenciesFromMessage(*message, &list));
    479     EXPECT_EQ(list.size(), arraysize(kScanFrequencyTrigger));
    480     int i = 0;
    481     vector<uint32_t>::const_iterator j = list.begin();
    482     while (j != list.end()) {
    483       EXPECT_EQ(kScanFrequencyTrigger[i], *j);
    484       ++i;
    485       ++j;
    486     }
    487   }
    488 
    489   {
    490     vector<string> ssids;
    491     EXPECT_TRUE(GetScanSsidsFromMessage(*message, &ssids));
    492     EXPECT_EQ(1, ssids.size());
    493     EXPECT_EQ(0, ssids[0].compare(""));  // Expect a single, empty SSID.
    494   }
    495 
    496   EXPECT_TRUE(message->const_attributes()->IsFlagAttributeTrue(
    497       NL80211_ATTR_SUPPORT_MESH_AUTH));
    498 }
    499 
    500 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_NEW_SCAN_RESULTS) {
    501   NetlinkPacket new_scan_results_packet(
    502       kNL80211_CMD_NEW_SCAN_RESULTS, sizeof(kNL80211_CMD_NEW_SCAN_RESULTS));
    503   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    504       &new_scan_results_packet, NetlinkMessage::MessageContext()));
    505 
    506   EXPECT_NE(nullptr, netlink_message);
    507   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    508   // The following is legal if the message_type is kNl80211FamilyId.
    509   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    510       netlink_message.release()));
    511 
    512   EXPECT_EQ(NL80211_CMD_NEW_SCAN_RESULTS, message->command());
    513 
    514   {
    515     uint32_t value;
    516     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    517         NL80211_ATTR_WIPHY, &value));
    518     EXPECT_EQ(kWiPhy, value);
    519   }
    520 
    521   {
    522     uint32_t value;
    523     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    524         NL80211_ATTR_IFINDEX, &value));
    525     EXPECT_EQ(kExpectedIfIndex, value);
    526   }
    527 
    528   // Make sure the scan frequencies in the attribute are the ones we expect.
    529   {
    530     vector<uint32_t>list;
    531     EXPECT_TRUE(GetScanFrequenciesFromMessage(*message, &list));
    532     EXPECT_EQ(arraysize(kScanFrequencyResults), list.size());
    533     int i = 0;
    534     vector<uint32_t>::const_iterator j = list.begin();
    535     while (j != list.end()) {
    536       EXPECT_EQ(kScanFrequencyResults[i], *j);
    537       ++i;
    538       ++j;
    539     }
    540   }
    541 
    542   {
    543     vector<string> ssids;
    544     EXPECT_TRUE(GetScanSsidsFromMessage(*message, &ssids));
    545     EXPECT_EQ(1, ssids.size());
    546     EXPECT_EQ(0, ssids[0].compare(""));  // Expect a single, empty SSID.
    547   }
    548 
    549   EXPECT_TRUE(message->const_attributes()->IsFlagAttributeTrue(
    550       NL80211_ATTR_SUPPORT_MESH_AUTH));
    551 }
    552 
    553 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_NEW_STATION) {
    554   NetlinkPacket netlink_packet(
    555       kNL80211_CMD_NEW_STATION, sizeof(kNL80211_CMD_NEW_STATION));
    556   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    557       &netlink_packet, NetlinkMessage::MessageContext()));
    558 
    559   EXPECT_NE(nullptr, netlink_message);
    560   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    561   // The following is legal if the message_type is kNl80211FamilyId.
    562   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    563       netlink_message.release()));
    564   EXPECT_EQ(NL80211_CMD_NEW_STATION, message->command());
    565 
    566   {
    567     uint32_t value;
    568     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    569         NL80211_ATTR_IFINDEX, &value));
    570     EXPECT_EQ(kExpectedIfIndex, value);
    571   }
    572 
    573   {
    574     string value;
    575     EXPECT_TRUE(message->const_attributes()->GetAttributeAsString(
    576         NL80211_ATTR_MAC, &value));
    577     EXPECT_EQ(0, strncmp(value.c_str(), kExpectedMacAddress, value.length()));
    578   }
    579 
    580   {
    581     AttributeListConstRefPtr nested;
    582     EXPECT_TRUE(message->const_attributes()->ConstGetNestedAttributeList(
    583         NL80211_ATTR_STA_INFO, &nested));
    584   }
    585 
    586   {
    587     uint32_t value;
    588     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    589         NL80211_ATTR_GENERATION, &value));
    590     EXPECT_EQ(kNewStationExpectedGeneration, value);
    591   }
    592 }
    593 
    594 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_AUTHENTICATE) {
    595   NetlinkPacket netlink_packet(
    596       kNL80211_CMD_AUTHENTICATE, sizeof(kNL80211_CMD_AUTHENTICATE));
    597   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    598       &netlink_packet, NetlinkMessage::MessageContext()));
    599 
    600   EXPECT_NE(nullptr, netlink_message);
    601   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    602   // The following is legal if the message_type is kNl80211FamilyId.
    603   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    604       netlink_message.release()));
    605   EXPECT_EQ(NL80211_CMD_AUTHENTICATE, message->command());
    606 
    607   {
    608     uint32_t value;
    609     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    610         NL80211_ATTR_WIPHY, &value));
    611     EXPECT_EQ(kWiPhy, value);
    612   }
    613 
    614   {
    615     uint32_t value;
    616     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    617         NL80211_ATTR_IFINDEX, &value));
    618     EXPECT_EQ(kExpectedIfIndex, value);
    619   }
    620 
    621   {
    622     ByteString rawdata;
    623     EXPECT_TRUE(message->const_attributes()->GetRawAttributeValue(
    624         NL80211_ATTR_FRAME, &rawdata));
    625     EXPECT_FALSE(rawdata.IsEmpty());
    626     Nl80211Frame frame(rawdata);
    627     Nl80211Frame expected_frame(ByteString(kAuthenticateFrame,
    628                                            sizeof(kAuthenticateFrame)));
    629     EXPECT_EQ(Nl80211Frame::kAuthFrameType, frame.frame_type());
    630     EXPECT_TRUE(frame.IsEqual(expected_frame));
    631   }
    632 }
    633 
    634 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_ASSOCIATE) {
    635   NetlinkPacket netlink_packet(
    636       kNL80211_CMD_ASSOCIATE, sizeof(kNL80211_CMD_ASSOCIATE));
    637   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    638       &netlink_packet, NetlinkMessage::MessageContext()));
    639 
    640   EXPECT_NE(nullptr, netlink_message);
    641   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    642   // The following is legal if the message_type is kNl80211FamilyId.
    643   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    644       netlink_message.release()));
    645   EXPECT_EQ(NL80211_CMD_ASSOCIATE, message->command());
    646 
    647   {
    648     uint32_t value;
    649     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    650         NL80211_ATTR_WIPHY, &value));
    651     EXPECT_EQ(kWiPhy, value);
    652   }
    653 
    654   {
    655     uint32_t value;
    656     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    657         NL80211_ATTR_IFINDEX, &value));
    658     EXPECT_EQ(kExpectedIfIndex, value);
    659   }
    660 
    661   {
    662     ByteString rawdata;
    663     EXPECT_TRUE(message->const_attributes()->GetRawAttributeValue(
    664         NL80211_ATTR_FRAME, &rawdata));
    665     EXPECT_FALSE(rawdata.IsEmpty());
    666     Nl80211Frame frame(rawdata);
    667     Nl80211Frame expected_frame(ByteString(kAssociateFrame,
    668                                            sizeof(kAssociateFrame)));
    669     EXPECT_EQ(Nl80211Frame::kAssocResponseFrameType, frame.frame_type());
    670     EXPECT_TRUE(frame.IsEqual(expected_frame));
    671   }
    672 }
    673 
    674 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_CONNECT) {
    675   NetlinkPacket netlink_packet(
    676       kNL80211_CMD_CONNECT, sizeof(kNL80211_CMD_CONNECT));
    677   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    678       &netlink_packet, NetlinkMessage::MessageContext()));
    679 
    680   EXPECT_NE(nullptr, netlink_message);
    681   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    682   // The following is legal if the message_type is kNl80211FamilyId.
    683   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    684       netlink_message.release()));
    685   EXPECT_EQ(NL80211_CMD_CONNECT, message->command());
    686 
    687   {
    688     uint32_t value;
    689     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    690         NL80211_ATTR_WIPHY, &value));
    691     EXPECT_EQ(kWiPhy, value);
    692   }
    693 
    694   {
    695     uint32_t value;
    696     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    697         NL80211_ATTR_IFINDEX, &value));
    698     EXPECT_EQ(kExpectedIfIndex, value);
    699   }
    700 
    701   {
    702     string value;
    703     EXPECT_TRUE(message->const_attributes()->GetAttributeAsString(
    704         NL80211_ATTR_MAC, &value));
    705     EXPECT_EQ(0, strncmp(value.c_str(), kExpectedMacAddress, value.length()));
    706   }
    707 
    708   {
    709     uint16_t value;
    710     EXPECT_TRUE(message->const_attributes()->GetU16AttributeValue(
    711         NL80211_ATTR_STATUS_CODE, &value));
    712     EXPECT_EQ(kExpectedConnectStatus, value);
    713   }
    714 
    715   {
    716     ByteString rawdata;
    717     EXPECT_TRUE(message->const_attributes()->GetRawAttributeValue(
    718         NL80211_ATTR_RESP_IE, &rawdata));
    719     EXPECT_TRUE(rawdata.Equals(
    720         ByteString(kRespIeBytes, arraysize(kRespIeBytes))));
    721   }
    722 }
    723 
    724 TEST_F(NetlinkMessageTest, Build_NL80211_CMD_CONNECT) {
    725   // Build the message that is found in kNL80211_CMD_CONNECT.
    726   ConnectMessage message;
    727   EXPECT_TRUE(message.attributes()->CreateNl80211Attribute(
    728       NL80211_ATTR_WIPHY, NetlinkMessage::MessageContext()));
    729   EXPECT_TRUE(
    730       message.attributes()->SetU32AttributeValue(NL80211_ATTR_WIPHY, kWiPhy));
    731 
    732   EXPECT_TRUE(message.attributes()->CreateNl80211Attribute(
    733       NL80211_ATTR_IFINDEX, NetlinkMessage::MessageContext()));
    734   EXPECT_TRUE(message.attributes()->SetU32AttributeValue(
    735       NL80211_ATTR_IFINDEX, kExpectedIfIndex));
    736 
    737   EXPECT_TRUE(message.attributes()->CreateNl80211Attribute(
    738       NL80211_ATTR_MAC, NetlinkMessage::MessageContext()));
    739   EXPECT_TRUE(message.attributes()->SetRawAttributeValue(NL80211_ATTR_MAC,
    740       ByteString(kMacAddressBytes, arraysize(kMacAddressBytes))));
    741 
    742   // In the middle, let's try adding an attribute without populating it.
    743   EXPECT_TRUE(message.attributes()->CreateNl80211Attribute(
    744       NL80211_ATTR_REG_TYPE, NetlinkMessage::MessageContext()));
    745 
    746   EXPECT_TRUE(message.attributes()->CreateNl80211Attribute(
    747       NL80211_ATTR_STATUS_CODE, NetlinkMessage::MessageContext()));
    748   EXPECT_TRUE(message.attributes()->SetU16AttributeValue(
    749       NL80211_ATTR_STATUS_CODE, kExpectedConnectStatus));
    750 
    751   EXPECT_TRUE(message.attributes()->CreateNl80211Attribute(
    752       NL80211_ATTR_RESP_IE, NetlinkMessage::MessageContext()));
    753   EXPECT_TRUE(message.attributes()->SetRawAttributeValue(NL80211_ATTR_RESP_IE,
    754       ByteString(kRespIeBytes, arraysize(kRespIeBytes))));
    755 
    756   // Encode the message to a ByteString and remove all the run-specific
    757   // values.
    758   static const uint32_t kArbitrarySequenceNumber = 42;
    759   ByteString message_bytes = message.Encode(kArbitrarySequenceNumber);
    760   nlmsghdr* header = reinterpret_cast<nlmsghdr*>(message_bytes.GetData());
    761   header->nlmsg_flags = 0;  // Overwrite with known values.
    762   header->nlmsg_seq = 0;
    763   header->nlmsg_pid = 0;
    764 
    765   // Verify that the messages are equal.
    766   EXPECT_TRUE(message_bytes.Equals(
    767       ByteString(kNL80211_CMD_CONNECT, arraysize(kNL80211_CMD_CONNECT))));
    768 }
    769 
    770 
    771 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_DEAUTHENTICATE) {
    772   NetlinkPacket netlink_packet(
    773       kNL80211_CMD_DEAUTHENTICATE, sizeof(kNL80211_CMD_DEAUTHENTICATE));
    774   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    775       &netlink_packet, NetlinkMessage::MessageContext()));
    776 
    777   EXPECT_NE(nullptr, netlink_message);
    778   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    779   // The following is legal if the message_type is kNl80211FamilyId.
    780   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    781       netlink_message.release()));
    782   EXPECT_EQ(NL80211_CMD_DEAUTHENTICATE, message->command());
    783 
    784   {
    785     uint32_t value;
    786     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    787         NL80211_ATTR_WIPHY, &value));
    788     EXPECT_EQ(kWiPhy, value);
    789   }
    790 
    791   {
    792     uint32_t value;
    793     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    794         NL80211_ATTR_IFINDEX, &value));
    795     EXPECT_EQ(kExpectedIfIndex, value);
    796   }
    797 
    798   {
    799     ByteString rawdata;
    800     EXPECT_TRUE(message->const_attributes()->GetRawAttributeValue(
    801         NL80211_ATTR_FRAME, &rawdata));
    802     EXPECT_FALSE(rawdata.IsEmpty());
    803     Nl80211Frame frame(rawdata);
    804     Nl80211Frame expected_frame(ByteString(kDeauthenticateFrame,
    805                                            sizeof(kDeauthenticateFrame)));
    806     EXPECT_EQ(Nl80211Frame::kDeauthFrameType, frame.frame_type());
    807     EXPECT_TRUE(frame.IsEqual(expected_frame));
    808   }
    809 }
    810 
    811 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_DISCONNECT) {
    812   NetlinkPacket netlink_packet(
    813       kNL80211_CMD_DISCONNECT, sizeof(kNL80211_CMD_DISCONNECT));
    814   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    815       &netlink_packet, NetlinkMessage::MessageContext()));
    816 
    817   EXPECT_NE(nullptr, netlink_message);
    818   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    819   // The following is legal if the message_type is kNl80211FamilyId.
    820   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    821       netlink_message.release()));
    822   EXPECT_EQ(NL80211_CMD_DISCONNECT, message->command());
    823 
    824   {
    825     uint32_t value;
    826     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    827         NL80211_ATTR_WIPHY, &value));
    828     EXPECT_EQ(kWiPhy, value);
    829   }
    830 
    831   {
    832     uint32_t value;
    833     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    834         NL80211_ATTR_IFINDEX, &value));
    835     EXPECT_EQ(kExpectedIfIndex, value);
    836   }
    837 
    838   {
    839     uint16_t value;
    840     EXPECT_TRUE(message->const_attributes()->GetU16AttributeValue(
    841         NL80211_ATTR_REASON_CODE, &value));
    842     EXPECT_EQ(kExpectedDisconnectReason, value);
    843   }
    844 
    845   EXPECT_TRUE(message->const_attributes()->IsFlagAttributeTrue(
    846       NL80211_ATTR_DISCONNECTED_BY_AP));
    847 }
    848 
    849 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_NOTIFY_CQM) {
    850   NetlinkPacket netlink_packet(
    851       kNL80211_CMD_NOTIFY_CQM, sizeof(kNL80211_CMD_NOTIFY_CQM));
    852   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    853       &netlink_packet, NetlinkMessage::MessageContext()));
    854 
    855   EXPECT_NE(nullptr, netlink_message);
    856   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    857   // The following is legal if the message_type is kNl80211FamilyId.
    858   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    859       netlink_message.release()));
    860   EXPECT_EQ(NL80211_CMD_NOTIFY_CQM, message->command());
    861 
    862   {
    863     uint32_t value;
    864     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    865         NL80211_ATTR_WIPHY, &value));
    866     EXPECT_EQ(kWiPhy, value);
    867   }
    868 
    869   {
    870     uint32_t value;
    871     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    872         NL80211_ATTR_IFINDEX, &value));
    873     EXPECT_EQ(kExpectedIfIndex, value);
    874   }
    875 
    876   {
    877     string value;
    878     EXPECT_TRUE(message->const_attributes()->GetAttributeAsString(
    879         NL80211_ATTR_MAC, &value));
    880     EXPECT_EQ(0, strncmp(value.c_str(), kExpectedMacAddress, value.length()));
    881   }
    882 
    883   {
    884     AttributeListConstRefPtr nested;
    885     EXPECT_TRUE(message->const_attributes()->ConstGetNestedAttributeList(
    886         NL80211_ATTR_CQM, &nested));
    887     uint32_t threshold_event;
    888     EXPECT_FALSE(nested->GetU32AttributeValue(
    889         NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, &threshold_event));
    890     uint32_t pkt_loss_event;
    891     EXPECT_TRUE(nested->GetU32AttributeValue(
    892         NL80211_ATTR_CQM_PKT_LOSS_EVENT, &pkt_loss_event));
    893     EXPECT_EQ(kExpectedCqmNotAcked, pkt_loss_event);
    894   }
    895 }
    896 
    897 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_DISASSOCIATE) {
    898   NetlinkPacket netlink_packet(
    899       kNL80211_CMD_DISASSOCIATE, sizeof(kNL80211_CMD_DISASSOCIATE));
    900   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    901       &netlink_packet, NetlinkMessage::MessageContext()));
    902 
    903   EXPECT_NE(nullptr, netlink_message);
    904   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    905   // The following is legal if the message_type is kNl80211FamilyId.
    906   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    907       netlink_message.release()));
    908   EXPECT_EQ(NL80211_CMD_DISASSOCIATE, message->command());
    909 
    910 
    911   {
    912     uint32_t value;
    913     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    914         NL80211_ATTR_WIPHY, &value));
    915     EXPECT_EQ(kWiPhy, value);
    916   }
    917 
    918   {
    919     uint32_t value;
    920     EXPECT_TRUE(message->const_attributes()->GetU32AttributeValue(
    921         NL80211_ATTR_IFINDEX, &value));
    922     EXPECT_EQ(kExpectedIfIndex, value);
    923   }
    924 
    925   {
    926     ByteString rawdata;
    927     EXPECT_TRUE(message->const_attributes()->GetRawAttributeValue(
    928         NL80211_ATTR_FRAME, &rawdata));
    929     EXPECT_FALSE(rawdata.IsEmpty());
    930     Nl80211Frame frame(rawdata);
    931     Nl80211Frame expected_frame(ByteString(kDisassociateFrame,
    932                                            sizeof(kDisassociateFrame)));
    933     EXPECT_EQ(Nl80211Frame::kDisassocFrameType, frame.frame_type());
    934     EXPECT_TRUE(frame.IsEqual(expected_frame));
    935   }
    936 }
    937 
    938 // This test is to ensure that an unknown nl80211 message generates an
    939 // Nl80211UnknownMessage with all Nl80211 parts.
    940 TEST_F(NetlinkMessageTest, Parse_NL80211_CMD_UNKNOWN) {
    941   NetlinkPacket netlink_packet(
    942       kNL80211_CMD_UNKNOWN, sizeof(kNL80211_CMD_UNKNOWN));
    943   unique_ptr<NetlinkMessage> netlink_message(message_factory_.CreateMessage(
    944       &netlink_packet, NetlinkMessage::MessageContext()));
    945   ASSERT_NE(nullptr, netlink_message.get());
    946   EXPECT_EQ(kNl80211FamilyId, netlink_message->message_type());
    947   // The following is legal if the message_type is kNl80211FamilyId.
    948   unique_ptr<Nl80211Message> message(static_cast<Nl80211Message*>(
    949       netlink_message.release()));
    950   EXPECT_EQ(kCmdNL80211_CMD_UNKNOWN, message->command());
    951 }
    952 
    953 }  // namespace shill
    954