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:
NetlinkMessageTest()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.
GetScanFrequenciesFromMessage(const Nl80211Message & message,vector<uint32_t> * value)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.
GetScanSsidsFromMessage(const Nl80211Message & message,vector<string> * value)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_TRIGGER_SCAN)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_NEW_SCAN_RESULTS)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_NEW_STATION)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_AUTHENTICATE)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_ASSOCIATE)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_CONNECT)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
TEST_F(NetlinkMessageTest,Build_NL80211_CMD_CONNECT)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_DEAUTHENTICATE)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_DISCONNECT)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_NOTIFY_CQM)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
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_DISASSOCIATE)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.
TEST_F(NetlinkMessageTest,Parse_NL80211_CMD_UNKNOWN)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