blob: 4bcf6f24d40180bcec72fa05ffe9b031c718d791 [file] [log] [blame]
Wade Guthrie0d438532012-05-18 14:18:50 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This file provides tests for individual messages. It tests
6// UserBoundNlMessageFactory's ability to create specific message types and it
7// tests the various UserBoundNlMessage types' ability to parse those
8// messages.
9
10// This file tests the public interface to Config80211.
11
12#include "shill/config80211.h"
13
Wade Guthrieb1ec8602012-10-18 17:26:14 -070014#include <list>
15#include <string>
16#include <vector>
17
18#include <base/bind.h>
Wade Guthrie0d438532012-05-18 14:18:50 -070019#include <gmock/gmock.h>
20#include <gtest/gtest.h>
21#include <netlink/attr.h>
22#include <netlink/netlink.h>
23
Wade Guthrieb1ec8602012-10-18 17:26:14 -070024#include "shill/mock_callback80211_object.h"
Wade Guthrie0d438532012-05-18 14:18:50 -070025#include "shill/mock_nl80211_socket.h"
26#include "shill/nl80211_socket.h"
27#include "shill/user_bound_nlmessage.h"
28
29using base::Bind;
30using base::Unretained;
Wade Guthrieb1ec8602012-10-18 17:26:14 -070031using std::list;
Wade Guthrie0d438532012-05-18 14:18:50 -070032using std::string;
33using std::vector;
34using testing::_;
35using testing::Return;
36using testing::Test;
37
38namespace shill {
39
40namespace {
41
42// These data blocks have been collected by shill using Config80211 while,
43// simultaneously (and manually) comparing shill output with that of the 'iw'
44// code from which it was derived. The test strings represent the raw packet
45// data coming from the kernel. The comments above each of these strings is
46// the markup that "iw" outputs for ech of these packets.
47
48// These constants are consistent throughout the packets, below.
49
50const uint32_t kExpectedIfIndex = 4;
51const uint8_t kExpectedWifi = 0;
52const char kExpectedMacAddress[] = "c0:3f:0e:77:e8:7f";
53
54
55// wlan0 (phy #0): scan started
56
57const uint32_t kScanFrequencyTrigger[] = {
58 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
59 2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200,
60 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520,
61 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
62 5700, 5745, 5765, 5785, 5805, 5825
63};
64
65const unsigned char kNL80211_CMD_TRIGGER_SCAN[] = {
66 0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x21, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
70 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00,
71 0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00,
72 0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00,
73 0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00,
74 0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00,
75 0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00,
76 0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00,
77 0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00,
78 0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00,
79 0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00,
80 0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00,
81 0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00,
82 0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00,
83 0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00,
84 0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00,
85 0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00,
86 0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00,
87 0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00,
88 0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00,
89 0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00,
90 0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00,
91 0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00,
92 0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00,
93 0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00,
94 0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00,
95 0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00,
96 0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00,
97 0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00,
98 0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00,
99 0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00,
100 0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00,
101 0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00,
102 0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00,
103 0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00,
104 0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00,
105 0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00,
106 0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00,
107 0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00,
108 0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00,
109 0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00,
110 0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
111};
112
113
114// wlan0 (phy #0): scan finished: 2412 2417 2422 2427 2432 2437 2442 2447 2452
115// 2457 2462 2467 2472 2484 5180 5200 5220 5240 5260 5280 5300 5320 5500 5520
116// 5540 5560 5580 5600 5620 5640 5660 5680 5700 5745 5765 5785 5805 5825, ""
117
118const uint32_t kScanFrequencyResults[] = {
119 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
120 2452, 2457, 2462, 2467, 2472, 2484, 5180, 5200,
121 5220, 5240, 5260, 5280, 5300, 5320, 5500, 5520,
122 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
123 5700, 5745, 5765, 5785, 5805, 5825
124};
125
126const unsigned char kNL80211_CMD_NEW_SCAN_RESULTS[] = {
127 0x68, 0x01, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x22, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
131 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x00,
132 0x04, 0x00, 0x00, 0x00, 0x34, 0x01, 0x2c, 0x00,
133 0x08, 0x00, 0x00, 0x00, 0x6c, 0x09, 0x00, 0x00,
134 0x08, 0x00, 0x01, 0x00, 0x71, 0x09, 0x00, 0x00,
135 0x08, 0x00, 0x02, 0x00, 0x76, 0x09, 0x00, 0x00,
136 0x08, 0x00, 0x03, 0x00, 0x7b, 0x09, 0x00, 0x00,
137 0x08, 0x00, 0x04, 0x00, 0x80, 0x09, 0x00, 0x00,
138 0x08, 0x00, 0x05, 0x00, 0x85, 0x09, 0x00, 0x00,
139 0x08, 0x00, 0x06, 0x00, 0x8a, 0x09, 0x00, 0x00,
140 0x08, 0x00, 0x07, 0x00, 0x8f, 0x09, 0x00, 0x00,
141 0x08, 0x00, 0x08, 0x00, 0x94, 0x09, 0x00, 0x00,
142 0x08, 0x00, 0x09, 0x00, 0x99, 0x09, 0x00, 0x00,
143 0x08, 0x00, 0x0a, 0x00, 0x9e, 0x09, 0x00, 0x00,
144 0x08, 0x00, 0x0b, 0x00, 0xa3, 0x09, 0x00, 0x00,
145 0x08, 0x00, 0x0c, 0x00, 0xa8, 0x09, 0x00, 0x00,
146 0x08, 0x00, 0x0d, 0x00, 0xb4, 0x09, 0x00, 0x00,
147 0x08, 0x00, 0x0e, 0x00, 0x3c, 0x14, 0x00, 0x00,
148 0x08, 0x00, 0x0f, 0x00, 0x50, 0x14, 0x00, 0x00,
149 0x08, 0x00, 0x10, 0x00, 0x64, 0x14, 0x00, 0x00,
150 0x08, 0x00, 0x11, 0x00, 0x78, 0x14, 0x00, 0x00,
151 0x08, 0x00, 0x12, 0x00, 0x8c, 0x14, 0x00, 0x00,
152 0x08, 0x00, 0x13, 0x00, 0xa0, 0x14, 0x00, 0x00,
153 0x08, 0x00, 0x14, 0x00, 0xb4, 0x14, 0x00, 0x00,
154 0x08, 0x00, 0x15, 0x00, 0xc8, 0x14, 0x00, 0x00,
155 0x08, 0x00, 0x16, 0x00, 0x7c, 0x15, 0x00, 0x00,
156 0x08, 0x00, 0x17, 0x00, 0x90, 0x15, 0x00, 0x00,
157 0x08, 0x00, 0x18, 0x00, 0xa4, 0x15, 0x00, 0x00,
158 0x08, 0x00, 0x19, 0x00, 0xb8, 0x15, 0x00, 0x00,
159 0x08, 0x00, 0x1a, 0x00, 0xcc, 0x15, 0x00, 0x00,
160 0x08, 0x00, 0x1b, 0x00, 0xe0, 0x15, 0x00, 0x00,
161 0x08, 0x00, 0x1c, 0x00, 0xf4, 0x15, 0x00, 0x00,
162 0x08, 0x00, 0x1d, 0x00, 0x08, 0x16, 0x00, 0x00,
163 0x08, 0x00, 0x1e, 0x00, 0x1c, 0x16, 0x00, 0x00,
164 0x08, 0x00, 0x1f, 0x00, 0x30, 0x16, 0x00, 0x00,
165 0x08, 0x00, 0x20, 0x00, 0x44, 0x16, 0x00, 0x00,
166 0x08, 0x00, 0x21, 0x00, 0x71, 0x16, 0x00, 0x00,
167 0x08, 0x00, 0x22, 0x00, 0x85, 0x16, 0x00, 0x00,
168 0x08, 0x00, 0x23, 0x00, 0x99, 0x16, 0x00, 0x00,
169 0x08, 0x00, 0x24, 0x00, 0xad, 0x16, 0x00, 0x00,
170 0x08, 0x00, 0x25, 0x00, 0xc1, 0x16, 0x00, 0x00,
171 0x08, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
172};
173
174
175// wlan0: new station c0:3f:0e:77:e8:7f
176
177const uint32_t kNewStationExpectedGeneration = 275;
178
179const unsigned char kNL80211_CMD_NEW_STATION[] = {
180 0x34, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x13, 0x01, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
183 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
184 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
185 0x08, 0x00, 0x2e, 0x00, 0x13, 0x01, 0x00, 0x00,
186 0x04, 0x00, 0x15, 0x00,
187};
188
189
190// wlan0 (phy #0): auth c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0:
191// Successful [frame: b0 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0
192// 3f 0e 77 e8 7f 30 07 00 00 02 00 00 00]
193
194const unsigned char kAuthenticateFrame[] = {
195 0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
196 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
197 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07,
198 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
199};
200
201const unsigned char kNL80211_CMD_AUTHENTICATE[] = {
202 0x48, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x25, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
206 0x04, 0x00, 0x00, 0x00, 0x22, 0x00, 0x33, 0x00,
207 0xb0, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
208 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
209 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x30, 0x07,
210 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
211};
212
213
214// wlan0 (phy #0): assoc c0:3f:0e:77:e8:7f -> 48:5d:60:77:2d:cf status: 0:
215// Successful [frame: 10 00 3a 01 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f c0 3f 0e
216// 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
217// 60 6c]
218
219const unsigned char kAssociateFrame[] = {
220 0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
221 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
222 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07,
223 0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08,
224 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24,
225 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c
226};
227
228const unsigned char kNL80211_CMD_ASSOCIATE[] = {
229 0x58, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x26, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
233 0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x33, 0x00,
234 0x10, 0x00, 0x3a, 0x01, 0x48, 0x5d, 0x60, 0x77,
235 0x2d, 0xcf, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
236 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x40, 0x07,
237 0x01, 0x04, 0x00, 0x00, 0x01, 0xc0, 0x01, 0x08,
238 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24,
239 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c, 0x00, 0x00,
240};
241
242
243// wlan0 (phy #0): connected to c0:3f:0e:77:e8:7f
244
245const uint16_t kExpectedConnectStatus = 0;
246
247const unsigned char kNL80211_CMD_CONNECT[] = {
248 0x4c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x2e, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
252 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
253 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
254 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x14, 0x00, 0x4e, 0x00, 0x01, 0x08, 0x82, 0x84,
256 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x32, 0x04,
257 0x30, 0x48, 0x60, 0x6c,
258};
259
260
261// wlan0 (phy #0): deauth c0:3f:0e:77:e8:7f -> ff:ff:ff:ff:ff:ff reason 2:
262// Previous authentication no longer valid [frame: c0 00 00 00 ff ff ff ff
263// ff ff c0 3f 0e 77 e8 7f c0 3f 0e 77 e8 7f c0 0e 02 00]
264
265const unsigned char kDeauthenticateFrame[] = {
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700266 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
267 0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
268 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
269 0x02, 0x00
Wade Guthrie0d438532012-05-18 14:18:50 -0700270};
271
272const unsigned char kNL80211_CMD_DEAUTHENTICATE[] = {
273 0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x27, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
277 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00,
278 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
279 0xff, 0xff, 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f,
280 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0xc0, 0x0e,
281 0x02, 0x00, 0x00, 0x00,
282};
283
284
285// wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no
286// longer valid
287
288const uint16_t kExpectedDisconnectReason = 2;
289
290const unsigned char kNL80211_CMD_DISCONNECT[] = {
291 0x30, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x30, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
295 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x36, 0x00,
296 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x47, 0x00,
297};
298
299
300// wlan0 (phy #0): connection quality monitor event: peer c0:3f:0e:77:e8:7f
301// didn't ACK 50 packets
302
303const uint32_t kExpectedCqmNotAcked = 50;
304
305const unsigned char kNL80211_CMD_NOTIFY_CQM[] = {
306 0x3c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x40, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
310 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x06, 0x00,
311 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
312 0x0c, 0x00, 0x5e, 0x00, 0x08, 0x00, 0x04, 0x00,
313 0x32, 0x00, 0x00, 0x00,
314};
315
316
317// wlan0 (phy #0): disassoc 48:5d:60:77:2d:cf -> c0:3f:0e:77:e8:7f reason 3:
318// Deauthenticated because sending station is [frame: a0 00 00 00 c0 3f 0e
319// 77 e8 7f 48 5d 60 77 2d cf c0 3f 0e 77 e8 7f 00 00 03 00]
320
321const unsigned char kDisassociateFrame[] = {
322 0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77,
323 0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf,
324 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
325 0x03, 0x00
326};
327
328const unsigned char kNL80211_CMD_DISASSOCIATE[] = {
329 0x44, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
331 0x28, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00,
333 0x04, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x33, 0x00,
334 0xa0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x0e, 0x77,
335 0xe8, 0x7f, 0x48, 0x5d, 0x60, 0x77, 0x2d, 0xcf,
336 0xc0, 0x3f, 0x0e, 0x77, 0xe8, 0x7f, 0x00, 0x00,
337 0x03, 0x00, 0x00, 0x00,
338};
339
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700340} // namespace
Wade Guthrie0d438532012-05-18 14:18:50 -0700341
342class Config80211Test : public Test {
343 public:
344 Config80211Test() : config80211_(Config80211::GetInstance()) {}
345 void SetupConfig80211Object() {
346 EXPECT_NE(config80211_, reinterpret_cast<Config80211 *>(NULL));
347 config80211_->sock_ = &socket_;
348 EXPECT_TRUE(config80211_->Init(reinterpret_cast<EventDispatcher *>(NULL)));
Wade Guthried6153612012-08-23 11:36:14 -0700349 config80211_->Reset();
Wade Guthrie0d438532012-05-18 14:18:50 -0700350 }
351
352 Config80211 *config80211_;
353 MockNl80211Socket socket_;
354};
355
356class TestCallbackObject {
357 public:
358 TestCallbackObject() : callback_(Bind(&TestCallbackObject::MessageHandler,
359 Unretained(this))) { }
360 void MessageHandler(const UserBoundNlMessage &msg) {
361 }
362 const Config80211::Callback &GetCallback() const { return callback_; }
363
364 private:
365 Config80211::Callback callback_;
366};
367
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700368// Checks a config80211 parameter to make sure it contains |callback_arg|
369// in its list of broadcast callbacks.
370MATCHER_P(ContainsCallback, callback_arg, "") {
371 if (arg == reinterpret_cast<void *>(NULL)) {
372 LOG(WARNING) << "NULL parameter";
Wade Guthrie0d438532012-05-18 14:18:50 -0700373 return false;
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700374 }
375 const Config80211 *config80211 = static_cast<Config80211 *>(arg);
376 const Config80211::Callback callback =
377 static_cast<const Config80211::Callback>(callback_arg);
378
379 return config80211->FindBroadcastCallback(callback);
Wade Guthrie0d438532012-05-18 14:18:50 -0700380}
381
382TEST_F(Config80211Test, AddLinkTest) {
383 SetupConfig80211Object();
384
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700385 // Create a broadcast callback.
Wade Guthrie0d438532012-05-18 14:18:50 -0700386 TestCallbackObject callback_object;
387
Wade Guthried6153612012-08-23 11:36:14 -0700388 // Install the callback and subscribe to events using it, wifi down
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700389 // (shouldn't actually send the subscription request until wifi comes up).
Wade Guthried6153612012-08-23 11:36:14 -0700390 EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
391 EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700392 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthried6153612012-08-23 11:36:14 -0700393
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700394 EXPECT_TRUE(config80211_->AddBroadcastCallback(
395 callback_object.GetCallback()));
Wade Guthried6153612012-08-23 11:36:14 -0700396 Config80211::EventType scan_event = Config80211::kEventTypeScan;
397 string scan_event_string;
398 EXPECT_TRUE(Config80211::GetEventTypeString(scan_event, &scan_event_string));
399 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
400
401 // Wifi up, should subscribe to events.
402 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700403 .WillOnce(Return(true));
404 EXPECT_CALL(socket_, DisableSequenceChecking())
405 .WillOnce(Return(true));
406 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700407 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthrie0d438532012-05-18 14:18:50 -0700408 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700409 config80211_->SetWifiState(Config80211::kWifiUp);
Wade Guthrie0d438532012-05-18 14:18:50 -0700410
Wade Guthried6153612012-08-23 11:36:14 -0700411 // Second subscribe, same event (should do nothing).
412 EXPECT_CALL(socket_, AddGroupMembership(_)).Times(0);
413 EXPECT_CALL(socket_, DisableSequenceChecking()).Times(0);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700414 EXPECT_CALL(socket_, SetNetlinkCallback(_, _)).Times(0);
Wade Guthried6153612012-08-23 11:36:14 -0700415 EXPECT_TRUE(config80211_->SubscribeToEvents(scan_event));
Wade Guthrie0d438532012-05-18 14:18:50 -0700416
Wade Guthried6153612012-08-23 11:36:14 -0700417 // Bring the wifi back down.
418 config80211_->SetWifiState(Config80211::kWifiDown);
419
420 // Subscribe to a new event with the wifi down (should still do nothing).
421 Config80211::EventType mlme_event = Config80211::kEventTypeMlme;
422 string mlme_event_string;
423 EXPECT_TRUE(Config80211::GetEventTypeString(mlme_event, &mlme_event_string));
424 EXPECT_TRUE(config80211_->SubscribeToEvents(mlme_event));
425
426 // Wifi up (again), should subscribe to the original scan event and the new
427 // mlme event.
428 EXPECT_CALL(socket_, AddGroupMembership(scan_event_string))
Wade Guthrie0d438532012-05-18 14:18:50 -0700429 .WillOnce(Return(true));
Wade Guthried6153612012-08-23 11:36:14 -0700430 EXPECT_CALL(socket_, AddGroupMembership(mlme_event_string))
431 .WillOnce(Return(true));
432 EXPECT_CALL(socket_, DisableSequenceChecking())
433 .Times(2)
434 .WillRepeatedly(Return(true));
435 EXPECT_CALL(socket_, SetNetlinkCallback(
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700436 _, ContainsCallback(callback_object.GetCallback())))
Wade Guthried6153612012-08-23 11:36:14 -0700437 .Times(2)
438 .WillRepeatedly(Return(true));
439 config80211_->SetWifiState(Config80211::kWifiUp);
Wade Guthrie0d438532012-05-18 14:18:50 -0700440}
441
442TEST_F(Config80211Test, NL80211_CMD_TRIGGER_SCAN) {
443 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
444 const_cast<nlmsghdr *>(
445 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_TRIGGER_SCAN)));
446
447 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
448 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_TRIGGER_SCAN);
449
450 {
451 uint8_t value;
452 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
453 EXPECT_EQ(value, kExpectedWifi);
454 }
455
456 {
457 uint32_t value;
458 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
459 EXPECT_EQ(value, kExpectedIfIndex);
460 }
461
462 // Make sure the scan frequencies in the attribute are the ones we expect.
463 {
464 vector<uint32_t>list;
465 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
466 NL80211_ATTR_SCAN_FREQUENCIES, &list));
467 EXPECT_EQ(arraysize(kScanFrequencyTrigger), list.size());
468 int i = 0;
469 vector<uint32_t>::const_iterator j = list.begin();
470 while (j != list.end()) {
471 EXPECT_EQ(kScanFrequencyTrigger[i], *j);
472 ++i;
473 ++j;
474 }
475 }
476
477 {
478 vector<string> ssids;
479 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
480 &ssids));
481 EXPECT_EQ(ssids.size(), 1);
482 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
483 }
484
485 // Significant only in its existence.
486 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
487}
488
489TEST_F(Config80211Test, NL80211_CMD_NEW_SCAN_RESULTS) {
490 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
491 const_cast<nlmsghdr *>(
492 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_SCAN_RESULTS)));
493
494 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
495 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_SCAN_RESULTS);
496
497 {
498 uint8_t value;
499 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
500 EXPECT_EQ(value, kExpectedWifi);
501 }
502
503 {
504 uint32_t value;
505 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
506 EXPECT_EQ(value, kExpectedIfIndex);
507 }
508
509 // Make sure the scan frequencies in the attribute are the ones we expect.
510 {
511 vector<uint32_t>list;
512 EXPECT_TRUE(message->GetScanFrequenciesAttribute(
513 NL80211_ATTR_SCAN_FREQUENCIES, &list));
514 EXPECT_EQ(arraysize(kScanFrequencyResults), list.size());
515 int i = 0;
516 vector<uint32_t>::const_iterator j = list.begin();
517 while (j != list.end()) {
518 EXPECT_EQ(kScanFrequencyResults[i], *j);
519 ++i;
520 ++j;
521 }
522 }
523
524 {
525 vector<string> ssids;
526 EXPECT_TRUE(message->GetScanSsidsAttribute(NL80211_ATTR_SCAN_SSIDS,
527 &ssids));
528 EXPECT_EQ(ssids.size(), 1);
529 EXPECT_EQ(ssids[0].compare(""), 0); // Expect a single, empty SSID.
530 }
531
532 // Significant only in its existence.
533 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_SUPPORT_MESH_AUTH));
534}
535
536TEST_F(Config80211Test, NL80211_CMD_NEW_STATION) {
537 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
538 const_cast<nlmsghdr *>(
539 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NEW_STATION)));
540
541 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
542 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NEW_STATION);
543
544 {
545 uint32_t value;
546 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
547 EXPECT_EQ(value, kExpectedIfIndex);
548 }
549
550 {
551 string value;
552 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
553 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
554 }
555
556 // TODO(wdg): Make config80211 handle nested attributes so it can deal
557 // with things like NL80211_ATTR_STA_INFO (without just calling
558 // nla_parse_nested).
559 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_STA_INFO));
560
561 {
562 uint32_t value;
563 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_GENERATION, &value));
564 EXPECT_EQ(value, kNewStationExpectedGeneration);
565 }
566}
567
568TEST_F(Config80211Test, NL80211_CMD_AUTHENTICATE) {
569 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
570 const_cast<nlmsghdr *>(
571 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_AUTHENTICATE)));
572
573 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
574 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_AUTHENTICATE);
575
576 {
577 uint8_t value;
578 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
579 EXPECT_EQ(value, kExpectedWifi);
580 }
581
582 {
583 uint32_t value;
584 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
585 EXPECT_EQ(value, kExpectedIfIndex);
586 }
587
588 {
589 void *rawdata = NULL;
590 int frame_byte_count = 0;
591 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
592 &frame_byte_count));
593 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
594 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
595
596 Nl80211Frame frame(frame_data, frame_byte_count);
597 Nl80211Frame expected_frame(kAuthenticateFrame, sizeof(kAuthenticateFrame));
598
599 EXPECT_TRUE(frame.IsEqual(expected_frame));
600 }
601}
602
603TEST_F(Config80211Test, NL80211_CMD_ASSOCIATE) {
604 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
605 const_cast<nlmsghdr *>(
606 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_ASSOCIATE)));
607
608 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
609 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_ASSOCIATE);
610
611 {
612 uint8_t value;
613 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
614 EXPECT_EQ(value, kExpectedWifi);
615 }
616
617 {
618 uint32_t value;
619 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
620 EXPECT_EQ(value, kExpectedIfIndex);
621 }
622
623 {
624 void *rawdata = NULL;
625 int frame_byte_count = 0;
626 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
627 &frame_byte_count));
628 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
629 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
630
631 Nl80211Frame frame(frame_data, frame_byte_count);
632 Nl80211Frame expected_frame(kAssociateFrame, sizeof(kAssociateFrame));
633
634 EXPECT_TRUE(frame.IsEqual(expected_frame));
635 }
636}
637
638TEST_F(Config80211Test, NL80211_CMD_CONNECT) {
639 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
640 const_cast<nlmsghdr *>(
641 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_CONNECT)));
642
643 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
644 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_CONNECT);
645
646 {
647 uint8_t value;
648 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
649 EXPECT_EQ(value, kExpectedWifi);
650 }
651
652 {
653 uint32_t value;
654 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
655 EXPECT_EQ(value, kExpectedIfIndex);
656 }
657
658 {
659 string value;
660 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
661 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
662 }
663
664 {
665 uint16_t value;
666 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_STATUS_CODE, &value));
667 EXPECT_EQ(value, kExpectedConnectStatus);
668 }
669
670 // TODO(wdg): Need to check the value of this attribute.
671 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_RESP_IE));
672}
673
674TEST_F(Config80211Test, NL80211_CMD_DEAUTHENTICATE) {
675 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
676 const_cast<nlmsghdr *>(
677 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DEAUTHENTICATE)));
678
679 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
680 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DEAUTHENTICATE);
681
682 {
683 uint8_t value;
684 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
685 EXPECT_EQ(value, kExpectedWifi);
686 }
687
688 {
689 uint32_t value;
690 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
691 EXPECT_EQ(value, kExpectedIfIndex);
692 }
693
694 {
695 void *rawdata = NULL;
696 int frame_byte_count = 0;
697 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
698 &frame_byte_count));
699 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
700 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
701
702 Nl80211Frame frame(frame_data, frame_byte_count);
703 Nl80211Frame expected_frame(kDeauthenticateFrame,
704 sizeof(kDeauthenticateFrame));
705
706 EXPECT_TRUE(frame.IsEqual(expected_frame));
707 }
708}
709
710TEST_F(Config80211Test, NL80211_CMD_DISCONNECT) {
711 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
712 const_cast<nlmsghdr *>(
713 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISCONNECT)));
714
715 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
716 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISCONNECT);
717
718 {
719 uint8_t value;
720 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
721 EXPECT_EQ(value, kExpectedWifi);
722 }
723
724 {
725 uint32_t value;
726 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
727 EXPECT_EQ(value, kExpectedIfIndex);
728 }
729
730 {
731 uint16_t value;
732 EXPECT_TRUE(message->GetU16Attribute(NL80211_ATTR_REASON_CODE, &value));
733 EXPECT_EQ(value, kExpectedDisconnectReason);
734 }
735
736 // Significant only in its existence.
737 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_DISCONNECTED_BY_AP));
738}
739
740TEST_F(Config80211Test, NL80211_CMD_NOTIFY_CQM) {
741 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
742 const_cast<nlmsghdr *>(
743 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_NOTIFY_CQM)));
744
745 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
746 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_NOTIFY_CQM);
747
748
749 {
750 uint8_t value;
751 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
752 EXPECT_EQ(value, kExpectedWifi);
753 }
754
755 {
756 uint32_t value;
757 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
758 EXPECT_EQ(value, kExpectedIfIndex);
759 }
760
761 {
762 string value;
763 EXPECT_TRUE(message->GetMacAttributeString(NL80211_ATTR_MAC, &value));
764 EXPECT_EQ(strncmp(value.c_str(), kExpectedMacAddress, value.length()), 0);
765 }
766
767 // TODO(wdg): Make config80211 handle nested attributes so it can deal
768 // with things like NL80211_ATTR_CQM (without just calling nla_parse_nested).
769 {
770 static const nla_policy kCqmPolicy[NL80211_ATTR_CQM_MAX + 1] = {
771 { NLA_U32, 0, 0 }, // Who Knows?
772 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THOLD]
773 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_HYST]
774 { NLA_U32, 0, 0 }, // [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]
775 };
776
777 EXPECT_TRUE(message->AttributeExists(NL80211_ATTR_CQM));
778 const nlattr *const_data = message->GetAttribute(NL80211_ATTR_CQM);
779 nlattr *cqm_attr = const_cast<nlattr *>(const_data);
780 EXPECT_NE(cqm_attr, reinterpret_cast<nlattr *>(NULL));
781
782 nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
783 EXPECT_EQ(nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, cqm_attr,
784 const_cast<nla_policy *>(kCqmPolicy)), 0);
785
786 EXPECT_FALSE(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
787 EXPECT_TRUE(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
788 EXPECT_EQ(nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]),
789 kExpectedCqmNotAcked);
790 }
791}
792
793TEST_F(Config80211Test, NL80211_CMD_DISASSOCIATE) {
794 UserBoundNlMessage *message = UserBoundNlMessageFactory::CreateMessage(
795 const_cast<nlmsghdr *>(
796 reinterpret_cast<const nlmsghdr *>(kNL80211_CMD_DISASSOCIATE)));
797
798 EXPECT_NE(message, reinterpret_cast<UserBoundNlMessage *>(NULL));
799 EXPECT_EQ(message->GetMessageType(), NL80211_CMD_DISASSOCIATE);
800
801
802 {
803 uint8_t value;
804 EXPECT_TRUE(message->GetU8Attribute(NL80211_ATTR_WIPHY, &value));
805 EXPECT_EQ(value, kExpectedWifi);
806 }
807
808 {
809 uint32_t value;
810 EXPECT_TRUE(message->GetU32Attribute(NL80211_ATTR_IFINDEX, &value));
811 EXPECT_EQ(value, kExpectedIfIndex);
812 }
813
814 {
815 void *rawdata = NULL;
816 int frame_byte_count = 0;
817 EXPECT_TRUE(message->GetRawAttributeData(NL80211_ATTR_FRAME, &rawdata,
818 &frame_byte_count));
819 EXPECT_NE(rawdata, reinterpret_cast<void *>(NULL));
820 const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
821
822 Nl80211Frame frame(frame_data, frame_byte_count);
823 Nl80211Frame expected_frame(kDisassociateFrame, sizeof(kDisassociateFrame));
824
825 EXPECT_TRUE(frame.IsEqual(expected_frame));
826 }
827}
828
829} // namespace shill