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