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 
30 namespace shill {
31 
32 class NetlinkPacket;
33 
34 // Class for messages received from the mac80211 drivers by way of the
35 // cfg80211 kernel module.
36 class SHILL_EXPORT Nl80211Message : public GenericNetlinkMessage {
37  public:
38   static const char kMessageTypeString[];
39 
Nl80211Message(uint8_t command,const char * command_string)40   Nl80211Message(uint8_t command, const char* command_string)
41       : GenericNetlinkMessage(nl80211_message_type_, command, command_string) {}
~Nl80211Message()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 
command()52   uint8_t command() const { return command_; }
command_string()53   const char* command_string() const { return command_string_; }
message_type()54   uint16_t message_type() const { return message_type_; }
sequence_number()55   uint32_t sequence_number() const { return sequence_number_; }
set_sequence_number(uint32_t seq)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 
75 class 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;
reason()91   uint16_t reason() const { return reason_; }
status()92   uint16_t status() const { return status_; }
frame_type()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 
113 class SHILL_EXPORT AssociateMessage : public Nl80211Message {
114  public:
115   static const uint8_t kCommand;
116   static const char kCommandString[];
117 
AssociateMessage()118   AssociateMessage() : Nl80211Message(kCommand, kCommandString) {}
119 
120  private:
121   DISALLOW_COPY_AND_ASSIGN(AssociateMessage);
122 };
123 
124 
125 class SHILL_EXPORT AuthenticateMessage : public Nl80211Message {
126  public:
127   static const uint8_t kCommand;
128   static const char kCommandString[];
129 
AuthenticateMessage()130   AuthenticateMessage() : Nl80211Message(kCommand, kCommandString) {}
131 
132  private:
133   DISALLOW_COPY_AND_ASSIGN(AuthenticateMessage);
134 };
135 
136 
137 class SHILL_EXPORT CancelRemainOnChannelMessage : public Nl80211Message {
138  public:
139   static const uint8_t kCommand;
140   static const char kCommandString[];
141 
CancelRemainOnChannelMessage()142   CancelRemainOnChannelMessage()
143       : Nl80211Message(kCommand, kCommandString) {}
144 
145  private:
146   DISALLOW_COPY_AND_ASSIGN(CancelRemainOnChannelMessage);
147 };
148 
149 
150 class SHILL_EXPORT ConnectMessage : public Nl80211Message {
151  public:
152   static const uint8_t kCommand;
153   static const char kCommandString[];
154 
ConnectMessage()155   ConnectMessage() : Nl80211Message(kCommand, kCommandString) {}
156 
157  private:
158   DISALLOW_COPY_AND_ASSIGN(ConnectMessage);
159 };
160 
161 
162 class SHILL_EXPORT DeauthenticateMessage : public Nl80211Message {
163  public:
164   static const uint8_t kCommand;
165   static const char kCommandString[];
166 
DeauthenticateMessage()167   DeauthenticateMessage() : Nl80211Message(kCommand, kCommandString) {}
168 
169  private:
170   DISALLOW_COPY_AND_ASSIGN(DeauthenticateMessage);
171 };
172 
173 
174 class SHILL_EXPORT DeleteStationMessage : public Nl80211Message {
175  public:
176   static const uint8_t kCommand;
177   static const char kCommandString[];
178 
DeleteStationMessage()179   DeleteStationMessage() : Nl80211Message(kCommand, kCommandString) {}
180 
181  private:
182   DISALLOW_COPY_AND_ASSIGN(DeleteStationMessage);
183 };
184 
185 
186 class SHILL_EXPORT DisassociateMessage : public Nl80211Message {
187  public:
188   static const uint8_t kCommand;
189   static const char kCommandString[];
190 
DisassociateMessage()191   DisassociateMessage() : Nl80211Message(kCommand, kCommandString) {}
192 
193  private:
194   DISALLOW_COPY_AND_ASSIGN(DisassociateMessage);
195 };
196 
197 
198 class SHILL_EXPORT DisconnectMessage : public Nl80211Message {
199  public:
200   static const uint8_t kCommand;
201   static const char kCommandString[];
202 
DisconnectMessage()203   DisconnectMessage() : Nl80211Message(kCommand, kCommandString) {}
204 
205  private:
206   DISALLOW_COPY_AND_ASSIGN(DisconnectMessage);
207 };
208 
209 
210 class SHILL_EXPORT FrameTxStatusMessage : public Nl80211Message {
211  public:
212   static const uint8_t kCommand;
213   static const char kCommandString[];
214 
FrameTxStatusMessage()215   FrameTxStatusMessage() : Nl80211Message(kCommand, kCommandString) {}
216 
217  private:
218   DISALLOW_COPY_AND_ASSIGN(FrameTxStatusMessage);
219 };
220 
221 class SHILL_EXPORT GetRegMessage : public Nl80211Message {
222  public:
223   static const uint8_t kCommand;
224   static const char kCommandString[];
225 
GetRegMessage()226   GetRegMessage() : Nl80211Message(kCommand, kCommandString) {}
227 
228  private:
229   DISALLOW_COPY_AND_ASSIGN(GetRegMessage);
230 };
231 
232 class 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 
243 class SHILL_EXPORT SetWakeOnPacketConnMessage : public Nl80211Message {
244  public:
245   static const uint8_t kCommand;
246   static const char kCommandString[];
247 
SetWakeOnPacketConnMessage()248   SetWakeOnPacketConnMessage() : Nl80211Message(kCommand, kCommandString) {}
249 
250  private:
251   DISALLOW_COPY_AND_ASSIGN(SetWakeOnPacketConnMessage);
252 };
253 
254 class SHILL_EXPORT GetWakeOnPacketConnMessage : public Nl80211Message {
255  public:
256   static const uint8_t kCommand;
257   static const char kCommandString[];
258 
GetWakeOnPacketConnMessage()259   GetWakeOnPacketConnMessage() : Nl80211Message(kCommand, kCommandString) {}
260 
261  private:
262   DISALLOW_COPY_AND_ASSIGN(GetWakeOnPacketConnMessage);
263 };
264 
265 class 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 
277 class SHILL_EXPORT JoinIbssMessage : public Nl80211Message {
278  public:
279   static const uint8_t kCommand;
280   static const char kCommandString[];
281 
JoinIbssMessage()282   JoinIbssMessage() : Nl80211Message(kCommand, kCommandString) {}
283 
284  private:
285   DISALLOW_COPY_AND_ASSIGN(JoinIbssMessage);
286 };
287 
288 
289 class SHILL_EXPORT MichaelMicFailureMessage : public Nl80211Message {
290  public:
291   static const uint8_t kCommand;
292   static const char kCommandString[];
293 
MichaelMicFailureMessage()294   MichaelMicFailureMessage() : Nl80211Message(kCommand, kCommandString) {}
295 
296  private:
297   DISALLOW_COPY_AND_ASSIGN(MichaelMicFailureMessage);
298 };
299 
300 
301 class SHILL_EXPORT NewScanResultsMessage : public Nl80211Message {
302  public:
303   static const uint8_t kCommand;
304   static const char kCommandString[];
305 
NewScanResultsMessage()306   NewScanResultsMessage() : Nl80211Message(kCommand, kCommandString) {}
307 
308  private:
309   DISALLOW_COPY_AND_ASSIGN(NewScanResultsMessage);
310 };
311 
312 
313 class SHILL_EXPORT NewStationMessage : public Nl80211Message {
314  public:
315   static const uint8_t kCommand;
316   static const char kCommandString[];
317 
NewStationMessage()318   NewStationMessage() : Nl80211Message(kCommand, kCommandString) {}
319 
320  private:
321   DISALLOW_COPY_AND_ASSIGN(NewStationMessage);
322 };
323 
324 
325 class SHILL_EXPORT NewWiphyMessage : public Nl80211Message {
326  public:
327   static const uint8_t kCommand;
328   static const char kCommandString[];
329 
NewWiphyMessage()330   NewWiphyMessage() : Nl80211Message(kCommand, kCommandString) {}
331 
332  private:
333   DISALLOW_COPY_AND_ASSIGN(NewWiphyMessage);
334 };
335 
336 
337 class SHILL_EXPORT NotifyCqmMessage : public Nl80211Message {
338  public:
339   static const uint8_t kCommand;
340   static const char kCommandString[];
341 
NotifyCqmMessage()342   NotifyCqmMessage() : Nl80211Message(kCommand, kCommandString) {}
343 
344  private:
345   DISALLOW_COPY_AND_ASSIGN(NotifyCqmMessage);
346 };
347 
348 
349 class SHILL_EXPORT PmksaCandidateMessage : public Nl80211Message {
350  public:
351   static const uint8_t kCommand;
352   static const char kCommandString[];
353 
PmksaCandidateMessage()354   PmksaCandidateMessage() : Nl80211Message(kCommand, kCommandString) {}
355 
356  private:
357   DISALLOW_COPY_AND_ASSIGN(PmksaCandidateMessage);
358 };
359 
360 
361 class SHILL_EXPORT RegBeaconHintMessage : public Nl80211Message {
362  public:
363   static const uint8_t kCommand;
364   static const char kCommandString[];
365 
RegBeaconHintMessage()366   RegBeaconHintMessage() : Nl80211Message(kCommand, kCommandString) {}
367 
368  private:
369   DISALLOW_COPY_AND_ASSIGN(RegBeaconHintMessage);
370 };
371 
372 
373 class SHILL_EXPORT RegChangeMessage : public Nl80211Message {
374  public:
375   static const uint8_t kCommand;
376   static const char kCommandString[];
377 
RegChangeMessage()378   RegChangeMessage() : Nl80211Message(kCommand, kCommandString) {}
379 
380  private:
381   DISALLOW_COPY_AND_ASSIGN(RegChangeMessage);
382 };
383 
384 
385 class SHILL_EXPORT RemainOnChannelMessage : public Nl80211Message {
386  public:
387   static const uint8_t kCommand;
388   static const char kCommandString[];
389 
RemainOnChannelMessage()390   RemainOnChannelMessage() : Nl80211Message(kCommand, kCommandString) {}
391 
392  private:
393   DISALLOW_COPY_AND_ASSIGN(RemainOnChannelMessage);
394 };
395 
396 
397 class SHILL_EXPORT RoamMessage : public Nl80211Message {
398  public:
399   static const uint8_t kCommand;
400   static const char kCommandString[];
401 
RoamMessage()402   RoamMessage() : Nl80211Message(kCommand, kCommandString) {}
403 
404  private:
405   DISALLOW_COPY_AND_ASSIGN(RoamMessage);
406 };
407 
408 
409 class SHILL_EXPORT ScanAbortedMessage : public Nl80211Message {
410  public:
411   static const uint8_t kCommand;
412   static const char kCommandString[];
413 
ScanAbortedMessage()414   ScanAbortedMessage() : Nl80211Message(kCommand, kCommandString) {}
415 
416  private:
417   DISALLOW_COPY_AND_ASSIGN(ScanAbortedMessage);
418 };
419 
420 
421 class 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 
433 class 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 
445 class SHILL_EXPORT UnknownNl80211Message : public Nl80211Message {
446  public:
UnknownNl80211Message(uint8_t command)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 
457 class SHILL_EXPORT UnprotDeauthenticateMessage : public Nl80211Message {
458  public:
459   static const uint8_t kCommand;
460   static const char kCommandString[];
461 
UnprotDeauthenticateMessage()462   UnprotDeauthenticateMessage()
463       : Nl80211Message(kCommand, kCommandString) {}
464 
465  private:
466   DISALLOW_COPY_AND_ASSIGN(UnprotDeauthenticateMessage);
467 };
468 
469 
470 class SHILL_EXPORT UnprotDisassociateMessage : public Nl80211Message {
471  public:
472   static const uint8_t kCommand;
473   static const char kCommandString[];
474 
UnprotDisassociateMessage()475   UnprotDisassociateMessage() : Nl80211Message(kCommand, kCommandString) {}
476 
477  private:
478   DISALLOW_COPY_AND_ASSIGN(UnprotDisassociateMessage);
479 };
480 
481 
482 class 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 
493 class SHILL_EXPORT NewInterfaceMessage : public Nl80211Message {
494  public:
495   static const uint8_t kCommand;
496   static const char kCommandString[];
497 
NewInterfaceMessage()498   NewInterfaceMessage() : Nl80211Message(kCommand, kCommandString) {}
499 
500  private:
501   DISALLOW_COPY_AND_ASSIGN(NewInterfaceMessage);
502 };
503 
504 class 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 
515 class SHILL_EXPORT SurveyResultsMessage : public Nl80211Message {
516  public:
517   static const uint8_t kCommand;
518   static const char kCommandString[];
519 
SurveyResultsMessage()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 
529 class 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