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
38using base::Bind;
39using base::StringPrintf;
40using base::Unretained;
41using std::string;
42using std::unique_ptr;
43using std::vector;
44using testing::_;
45using testing::EndsWith;
46using testing::Invoke;
47using testing::Return;
48using testing::Test;
49
50namespace shill {
51
52namespace {
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
62const uint32_t kExpectedIfIndex = 4;
63const uint32_t kWiPhy = 0;
64const uint16_t kNl80211FamilyId = 0x13;
65const char kExpectedMacAddress[] = "c0:3f:0e:77:e8:7f";
66
67const uint8_t kMacAddressBytes[] = {
68  0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f
69};
70
71const 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
81const 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
89const 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
142const 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
150const 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
201const uint32_t kNewStationExpectedGeneration = 275;
202
203const 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
218const 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
225const 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
243const 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
252const 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
269const uint16_t kExpectedConnectStatus = 0;
270
271const 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
289const 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
296const 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
312const uint16_t kExpectedDisconnectReason = 2;
313
314const 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
327const uint32_t kExpectedCqmNotAcked = 50;
328
329const 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
345const 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
352const 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
367const unsigned char kCmdNL80211_CMD_UNKNOWN = 0xfe;
368const 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
380class 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
446TEST_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
500TEST_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
553TEST_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
594TEST_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
634TEST_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
674TEST_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
724TEST_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
771TEST_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
811TEST_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
849TEST_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
897TEST_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.
940TEST_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