1//
2// Copyright (C) 2012 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#ifndef SHILL_NET_NL80211_MESSAGE_H_
18#define SHILL_NET_NL80211_MESSAGE_H_
19
20#include <map>
21#include <string>
22#include <vector>
23
24#include <base/lazy_instance.h>
25
26#include "shill/net/byte_string.h"
27#include "shill/net/generic_netlink_message.h"
28#include "shill/net/shill_export.h"
29
30namespace shill {
31
32class NetlinkPacket;
33
34// Class for messages received from the mac80211 drivers by way of the
35// cfg80211 kernel module.
36class SHILL_EXPORT Nl80211Message : public GenericNetlinkMessage {
37 public:
38  static const char kMessageTypeString[];
39
40  Nl80211Message(uint8_t command, const char* command_string)
41      : GenericNetlinkMessage(nl80211_message_type_, command, command_string) {}
42  ~Nl80211Message() override {}
43
44  // Gets the family_id / message_type for all Nl80211 messages.
45  static uint16_t GetMessageType();
46
47  // Sets the family_id / message_type for all Nl80211 messages.
48  static void SetMessageType(uint16_t message_type);
49
50  bool InitFromPacket(NetlinkPacket* packet, MessageContext context) override;
51
52  uint8_t command() const { return command_; }
53  const char* command_string() const { return command_string_; }
54  uint16_t message_type() const { return message_type_; }
55  uint32_t sequence_number() const { return sequence_number_; }
56  void set_sequence_number(uint32_t seq) { sequence_number_ = seq; }
57
58  // Returns a string representing the passed-in |status| or |reason|, the
59  // value of which has been acquired from the kernel (for example, from the
60  // NL80211_ATTR_STATUS_CODE or NL80211_ATTR_REASON_CODE attribute).
61  static std::string StringFromReason(uint16_t reason);
62  static std::string StringFromStatus(uint16_t status);
63
64  // Message factory for all types of Nl80211 message.
65  static NetlinkMessage* CreateMessage(const NetlinkPacket& packet);
66
67 private:
68  static std::map<uint16_t, std::string>* reason_code_string_;
69  static std::map<uint16_t, std::string>* status_code_string_;
70  static uint16_t nl80211_message_type_;
71
72  DISALLOW_COPY_AND_ASSIGN(Nl80211Message);
73};
74
75class SHILL_EXPORT Nl80211Frame {
76 public:
77  enum Type {
78    kAssocResponseFrameType = 0x10,
79    kReassocResponseFrameType = 0x30,
80    kAssocRequestFrameType = 0x00,
81    kReassocRequestFrameType = 0x20,
82    kAuthFrameType = 0xb0,
83    kDisassocFrameType = 0xa0,
84    kDeauthFrameType = 0xc0,
85    kIllegalFrameType = 0xff
86  };
87
88  explicit Nl80211Frame(const ByteString& init);
89  bool ToString(std::string* output) const;
90  bool IsEqual(const Nl80211Frame& other) const;
91  uint16_t reason() const { return reason_; }
92  uint16_t status() const { return status_; }
93  uint8_t frame_type() const { return frame_type_; }
94
95 private:
96  static const uint8_t kMinimumFrameByteCount;
97  static const uint8_t kFrameTypeMask;
98
99  std::string mac_from_;
100  std::string mac_to_;
101  uint8_t frame_type_;
102  uint16_t reason_;
103  uint16_t status_;
104  ByteString frame_;
105
106  DISALLOW_COPY_AND_ASSIGN(Nl80211Frame);
107};
108
109//
110// Specific Nl80211Message types.
111//
112
113class SHILL_EXPORT AssociateMessage : public Nl80211Message {
114 public:
115  static const uint8_t kCommand;
116  static const char kCommandString[];
117
118  AssociateMessage() : Nl80211Message(kCommand, kCommandString) {}
119
120 private:
121  DISALLOW_COPY_AND_ASSIGN(AssociateMessage);
122};
123
124
125class SHILL_EXPORT AuthenticateMessage : public Nl80211Message {
126 public:
127  static const uint8_t kCommand;
128  static const char kCommandString[];
129
130  AuthenticateMessage() : Nl80211Message(kCommand, kCommandString) {}
131
132 private:
133  DISALLOW_COPY_AND_ASSIGN(AuthenticateMessage);
134};
135
136
137class SHILL_EXPORT CancelRemainOnChannelMessage : public Nl80211Message {
138 public:
139  static const uint8_t kCommand;
140  static const char kCommandString[];
141
142  CancelRemainOnChannelMessage()
143      : Nl80211Message(kCommand, kCommandString) {}
144
145 private:
146  DISALLOW_COPY_AND_ASSIGN(CancelRemainOnChannelMessage);
147};
148
149
150class SHILL_EXPORT ConnectMessage : public Nl80211Message {
151 public:
152  static const uint8_t kCommand;
153  static const char kCommandString[];
154
155  ConnectMessage() : Nl80211Message(kCommand, kCommandString) {}
156
157 private:
158  DISALLOW_COPY_AND_ASSIGN(ConnectMessage);
159};
160
161
162class SHILL_EXPORT DeauthenticateMessage : public Nl80211Message {
163 public:
164  static const uint8_t kCommand;
165  static const char kCommandString[];
166
167  DeauthenticateMessage() : Nl80211Message(kCommand, kCommandString) {}
168
169 private:
170  DISALLOW_COPY_AND_ASSIGN(DeauthenticateMessage);
171};
172
173
174class SHILL_EXPORT DeleteStationMessage : public Nl80211Message {
175 public:
176  static const uint8_t kCommand;
177  static const char kCommandString[];
178
179  DeleteStationMessage() : Nl80211Message(kCommand, kCommandString) {}
180
181 private:
182  DISALLOW_COPY_AND_ASSIGN(DeleteStationMessage);
183};
184
185
186class SHILL_EXPORT DisassociateMessage : public Nl80211Message {
187 public:
188  static const uint8_t kCommand;
189  static const char kCommandString[];
190
191  DisassociateMessage() : Nl80211Message(kCommand, kCommandString) {}
192
193 private:
194  DISALLOW_COPY_AND_ASSIGN(DisassociateMessage);
195};
196
197
198class SHILL_EXPORT DisconnectMessage : public Nl80211Message {
199 public:
200  static const uint8_t kCommand;
201  static const char kCommandString[];
202
203  DisconnectMessage() : Nl80211Message(kCommand, kCommandString) {}
204
205 private:
206  DISALLOW_COPY_AND_ASSIGN(DisconnectMessage);
207};
208
209
210class SHILL_EXPORT FrameTxStatusMessage : public Nl80211Message {
211 public:
212  static const uint8_t kCommand;
213  static const char kCommandString[];
214
215  FrameTxStatusMessage() : Nl80211Message(kCommand, kCommandString) {}
216
217 private:
218  DISALLOW_COPY_AND_ASSIGN(FrameTxStatusMessage);
219};
220
221class SHILL_EXPORT GetRegMessage : public Nl80211Message {
222 public:
223  static const uint8_t kCommand;
224  static const char kCommandString[];
225
226  GetRegMessage() : Nl80211Message(kCommand, kCommandString) {}
227
228 private:
229  DISALLOW_COPY_AND_ASSIGN(GetRegMessage);
230};
231
232class SHILL_EXPORT GetStationMessage : public Nl80211Message {
233 public:
234  static const uint8_t kCommand;
235  static const char kCommandString[];
236
237  GetStationMessage();
238
239 private:
240  DISALLOW_COPY_AND_ASSIGN(GetStationMessage);
241};
242
243class SHILL_EXPORT SetWakeOnPacketConnMessage : public Nl80211Message {
244 public:
245  static const uint8_t kCommand;
246  static const char kCommandString[];
247
248  SetWakeOnPacketConnMessage() : Nl80211Message(kCommand, kCommandString) {}
249
250 private:
251  DISALLOW_COPY_AND_ASSIGN(SetWakeOnPacketConnMessage);
252};
253
254class SHILL_EXPORT GetWakeOnPacketConnMessage : public Nl80211Message {
255 public:
256  static const uint8_t kCommand;
257  static const char kCommandString[];
258
259  GetWakeOnPacketConnMessage() : Nl80211Message(kCommand, kCommandString) {}
260
261 private:
262  DISALLOW_COPY_AND_ASSIGN(GetWakeOnPacketConnMessage);
263};
264
265class SHILL_EXPORT GetWiphyMessage : public Nl80211Message {
266 public:
267  static const uint8_t kCommand;
268  static const char kCommandString[];
269
270  GetWiphyMessage();
271
272 private:
273  DISALLOW_COPY_AND_ASSIGN(GetWiphyMessage);
274};
275
276
277class SHILL_EXPORT JoinIbssMessage : public Nl80211Message {
278 public:
279  static const uint8_t kCommand;
280  static const char kCommandString[];
281
282  JoinIbssMessage() : Nl80211Message(kCommand, kCommandString) {}
283
284 private:
285  DISALLOW_COPY_AND_ASSIGN(JoinIbssMessage);
286};
287
288
289class SHILL_EXPORT MichaelMicFailureMessage : public Nl80211Message {
290 public:
291  static const uint8_t kCommand;
292  static const char kCommandString[];
293
294  MichaelMicFailureMessage() : Nl80211Message(kCommand, kCommandString) {}
295
296 private:
297  DISALLOW_COPY_AND_ASSIGN(MichaelMicFailureMessage);
298};
299
300
301class SHILL_EXPORT NewScanResultsMessage : public Nl80211Message {
302 public:
303  static const uint8_t kCommand;
304  static const char kCommandString[];
305
306  NewScanResultsMessage() : Nl80211Message(kCommand, kCommandString) {}
307
308 private:
309  DISALLOW_COPY_AND_ASSIGN(NewScanResultsMessage);
310};
311
312
313class SHILL_EXPORT NewStationMessage : public Nl80211Message {
314 public:
315  static const uint8_t kCommand;
316  static const char kCommandString[];
317
318  NewStationMessage() : Nl80211Message(kCommand, kCommandString) {}
319
320 private:
321  DISALLOW_COPY_AND_ASSIGN(NewStationMessage);
322};
323
324
325class SHILL_EXPORT NewWiphyMessage : public Nl80211Message {
326 public:
327  static const uint8_t kCommand;
328  static const char kCommandString[];
329
330  NewWiphyMessage() : Nl80211Message(kCommand, kCommandString) {}
331
332 private:
333  DISALLOW_COPY_AND_ASSIGN(NewWiphyMessage);
334};
335
336
337class SHILL_EXPORT NotifyCqmMessage : public Nl80211Message {
338 public:
339  static const uint8_t kCommand;
340  static const char kCommandString[];
341
342  NotifyCqmMessage() : Nl80211Message(kCommand, kCommandString) {}
343
344 private:
345  DISALLOW_COPY_AND_ASSIGN(NotifyCqmMessage);
346};
347
348
349class SHILL_EXPORT PmksaCandidateMessage : public Nl80211Message {
350 public:
351  static const uint8_t kCommand;
352  static const char kCommandString[];
353
354  PmksaCandidateMessage() : Nl80211Message(kCommand, kCommandString) {}
355
356 private:
357  DISALLOW_COPY_AND_ASSIGN(PmksaCandidateMessage);
358};
359
360
361class SHILL_EXPORT RegBeaconHintMessage : public Nl80211Message {
362 public:
363  static const uint8_t kCommand;
364  static const char kCommandString[];
365
366  RegBeaconHintMessage() : Nl80211Message(kCommand, kCommandString) {}
367
368 private:
369  DISALLOW_COPY_AND_ASSIGN(RegBeaconHintMessage);
370};
371
372
373class SHILL_EXPORT RegChangeMessage : public Nl80211Message {
374 public:
375  static const uint8_t kCommand;
376  static const char kCommandString[];
377
378  RegChangeMessage() : Nl80211Message(kCommand, kCommandString) {}
379
380 private:
381  DISALLOW_COPY_AND_ASSIGN(RegChangeMessage);
382};
383
384
385class SHILL_EXPORT RemainOnChannelMessage : public Nl80211Message {
386 public:
387  static const uint8_t kCommand;
388  static const char kCommandString[];
389
390  RemainOnChannelMessage() : Nl80211Message(kCommand, kCommandString) {}
391
392 private:
393  DISALLOW_COPY_AND_ASSIGN(RemainOnChannelMessage);
394};
395
396
397class SHILL_EXPORT RoamMessage : public Nl80211Message {
398 public:
399  static const uint8_t kCommand;
400  static const char kCommandString[];
401
402  RoamMessage() : Nl80211Message(kCommand, kCommandString) {}
403
404 private:
405  DISALLOW_COPY_AND_ASSIGN(RoamMessage);
406};
407
408
409class SHILL_EXPORT ScanAbortedMessage : public Nl80211Message {
410 public:
411  static const uint8_t kCommand;
412  static const char kCommandString[];
413
414  ScanAbortedMessage() : Nl80211Message(kCommand, kCommandString) {}
415
416 private:
417  DISALLOW_COPY_AND_ASSIGN(ScanAbortedMessage);
418};
419
420
421class SHILL_EXPORT GetScanMessage : public Nl80211Message {
422 public:
423  static const uint8_t kCommand;
424  static const char kCommandString[];
425
426  GetScanMessage();
427
428 private:
429  DISALLOW_COPY_AND_ASSIGN(GetScanMessage);
430};
431
432
433class SHILL_EXPORT TriggerScanMessage : public Nl80211Message {
434 public:
435  static const uint8_t kCommand;
436  static const char kCommandString[];
437
438  TriggerScanMessage();
439
440 private:
441  DISALLOW_COPY_AND_ASSIGN(TriggerScanMessage);
442};
443
444
445class SHILL_EXPORT UnknownNl80211Message : public Nl80211Message {
446 public:
447  explicit UnknownNl80211Message(uint8_t command)
448      : Nl80211Message(command, "<UNKNOWN NL80211 MESSAGE>"),
449        command_(command) {}
450
451 private:
452  uint8_t command_;
453  DISALLOW_COPY_AND_ASSIGN(UnknownNl80211Message);
454};
455
456
457class SHILL_EXPORT UnprotDeauthenticateMessage : public Nl80211Message {
458 public:
459  static const uint8_t kCommand;
460  static const char kCommandString[];
461
462  UnprotDeauthenticateMessage()
463      : Nl80211Message(kCommand, kCommandString) {}
464
465 private:
466  DISALLOW_COPY_AND_ASSIGN(UnprotDeauthenticateMessage);
467};
468
469
470class SHILL_EXPORT UnprotDisassociateMessage : public Nl80211Message {
471 public:
472  static const uint8_t kCommand;
473  static const char kCommandString[];
474
475  UnprotDisassociateMessage() : Nl80211Message(kCommand, kCommandString) {}
476
477 private:
478  DISALLOW_COPY_AND_ASSIGN(UnprotDisassociateMessage);
479};
480
481
482class SHILL_EXPORT GetInterfaceMessage : public Nl80211Message {
483 public:
484  static const uint8_t kCommand;
485  static const char kCommandString[];
486
487  GetInterfaceMessage();
488
489 private:
490  DISALLOW_COPY_AND_ASSIGN(GetInterfaceMessage);
491};
492
493class SHILL_EXPORT NewInterfaceMessage : public Nl80211Message {
494 public:
495  static const uint8_t kCommand;
496  static const char kCommandString[];
497
498  NewInterfaceMessage() : Nl80211Message(kCommand, kCommandString) {}
499
500 private:
501  DISALLOW_COPY_AND_ASSIGN(NewInterfaceMessage);
502};
503
504class SHILL_EXPORT GetSurveyMessage : public Nl80211Message {
505 public:
506  static const uint8_t kCommand;
507  static const char kCommandString[];
508
509  GetSurveyMessage();
510
511 private:
512  DISALLOW_COPY_AND_ASSIGN(GetSurveyMessage);
513};
514
515class SHILL_EXPORT SurveyResultsMessage : public Nl80211Message {
516 public:
517  static const uint8_t kCommand;
518  static const char kCommandString[];
519
520  SurveyResultsMessage(): Nl80211Message(kCommand, kCommandString) {}
521
522 private:
523  DISALLOW_COPY_AND_ASSIGN(SurveyResultsMessage);
524};
525
526// Nl80211MessageDataCollector - this class is used to collect data to be
527// used for unit tests.  It is only invoked in this case.
528
529class Nl80211MessageDataCollector {
530 public:
531  static Nl80211MessageDataCollector* GetInstance();
532
533  void CollectDebugData(
534      const Nl80211Message& message, const NetlinkPacket& packet);
535
536 protected:
537  friend struct
538      base::DefaultLazyInstanceTraits<Nl80211MessageDataCollector>;
539
540  Nl80211MessageDataCollector();
541
542 private:
543  // In order to limit the output from this class, I keep track of types I
544  // haven't yet printed.
545  std::map<uint8_t, bool> need_to_print;
546
547  DISALLOW_COPY_AND_ASSIGN(Nl80211MessageDataCollector);
548};
549
550}  // namespace shill
551
552#endif  // SHILL_NET_NL80211_MESSAGE_H_
553