blob: aa9881cd8c3232a18c0a443ca7d98953579e2450 [file] [log] [blame]
Wade Guthrie0d438532012-05-18 14:18:50 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_USER_BOUND_NLMESSAGE_H_
6#define SHILL_USER_BOUND_NLMESSAGE_H_
7
8#include <iomanip>
9#include <map>
10#include <vector>
11#include <string>
12
13#include <base/basictypes.h>
14#include <base/bind.h>
15#include <base/lazy_instance.h>
16#include <gtest/gtest.h>
17
18#include <linux/nl80211.h>
19
20struct nlattr;
21struct nlmsghdr;
22
23namespace shill {
24
25// Class for messages received from libnl.
26class UserBoundNlMessage {
27 public:
28 enum Type {
29 kTypeUnspecified,
30 kTypeU8,
31 kTypeU16,
32 kTypeU32,
33 kTypeU64,
34 kTypeString,
35 kTypeFlag,
36 kTypeMsecs,
37 kTypeNested,
38 kTypeOther, // Specified in the message but not listed, here.
39 kTypeError
40 };
Wade Guthrie64b4c142012-08-20 15:21:01 -070041
Wade Guthrie0d438532012-05-18 14:18:50 -070042 // TODO(wdg): break 'Attribute' into its own class to handle
43 // nested attributes better.
44
45 // A const iterator to the attribute names in the attributes_ map of a
46 // UserBoundNlMessage. The purpose, here, is to hide the way that the
47 // attribute is stored.
48 class AttributeNameIterator {
49 public:
50 explicit AttributeNameIterator(const std::map<nl80211_attrs,
51 nlattr *> &map_param)
52 : map_(map_param) {
53 iter_ = map_.begin();
54 }
55
56 // Causes the iterator to point to the next attribute in the list.
57 void Advance() { ++iter_; }
58
59 // Returns 'true' if the iterator points beyond the last attribute in the
60 // list; returns 'false' otherwise.
61 bool AtEnd() const { return iter_ == map_.end(); }
62
63 // Returns the attribute name (which is actually an 'enum' value).
64 nl80211_attrs GetName() const { return iter_->first; }
65
66 private:
67 const std::map<nl80211_attrs, nlattr *> &map_;
68 std::map<nl80211_attrs, nlattr *>::const_iterator iter_;
69
70 DISALLOW_COPY_AND_ASSIGN(AttributeNameIterator);
71 };
72
73 static const uint8_t kCommand;
74 static const char kCommandString[];
75 static const char kBogusMacAddress[];
76
77 UserBoundNlMessage() : message_(NULL) { }
78 virtual ~UserBoundNlMessage();
79
80 // Non-trivial initialization.
81 virtual bool Init(nlattr *tb[NL80211_ATTR_MAX + 1], nlmsghdr *msg);
82
83 // Provide a suite of methods to allow (const) iteration over the names of the
84 // attributes inside a message object.
85
86 AttributeNameIterator *GetAttributeNameIterator() const;
87 bool HasAttributes() const { return !attributes_.empty(); }
88 uint32_t GetAttributeCount() const { return attributes_.size(); }
89
90 virtual uint8_t GetMessageType() const {
91 return UserBoundNlMessage::kCommand;
92 }
93 virtual std::string GetMessageTypeString() const {
94 return UserBoundNlMessage::kCommandString;
95 }
96
97 // Other ways to see the internals of the object.
98
99 // Return true if the attribute is in our map, regardless of the value of
100 // the attribute, itself.
101 bool AttributeExists(nl80211_attrs name) const;
102
103 // Message ID is equivalent to the message's sequence number.
104 uint32_t GetId() const;
105
106 // Returns the data type of a given attribute.
107 Type GetAttributeType(nl80211_attrs name) const;
108
109 // Returns a string describing the data type of a given attribute.
110 std::string GetAttributeTypeString(nl80211_attrs name) const;
111
112 // If successful, returns 'true' and sets *|value| to the raw attribute data
113 // (after the header) for this attribute and, if |length| is not
114 // null, *|length| to the number of bytes of data available. If no
115 // attribute by this name exists in this message, sets *|value| to NULL and
116 // returns 'false'. If otherwise unsuccessful, returns 'false' and leaves
117 // |value| and |length| unchanged.
118 bool GetRawAttributeData(nl80211_attrs name, void **value, int *length) const;
119
120 // Each of these methods set |value| with the value of the specified
121 // attribute (if the attribute is not found, |value| remains unchanged).
122
123 bool GetStringAttribute(nl80211_attrs name, std::string *value) const;
124 bool GetU8Attribute(nl80211_attrs name, uint8_t *value) const;
125 bool GetU16Attribute(nl80211_attrs name, uint16_t *value) const;
126 bool GetU32Attribute(nl80211_attrs name, uint32_t *value) const;
127 bool GetU64Attribute(nl80211_attrs name, uint64_t *value) const;
128
129 // Fill a string with characters that represents the value of the attribute.
130 // If no attribute is found or if the type isn't trivially stringizable,
131 // this method returns 'false' and |value| remains unchanged.
132 bool GetAttributeString(nl80211_attrs name, std::string *value) const;
133
134 // Helper function to provide a string for a MAC address. If no attribute
135 // is found, this method returns 'false'. On any error with a non-NULL
136 // |value|, this method sets |value| to a bogus MAC address.
137 bool GetMacAttributeString(nl80211_attrs name, std::string *value) const;
138
139 // Helper function to provide a vector of scan frequencies for attributes
140 // that contain them (such as NL80211_ATTR_SCAN_FREQUENCIES).
141 bool GetScanFrequenciesAttribute(enum nl80211_attrs name,
142 std::vector<uint32_t> *value) const;
143
144 // Helper function to provide a vector of SSIDs for attributes that contain
145 // them (such as NL80211_ATTR_SCAN_SSIDS).
146 bool GetScanSsidsAttribute(enum nl80211_attrs name,
147 std::vector<std::string> *value) const;
148
149 // Writes the raw attribute data to a string. For debug.
150 virtual std::string RawToString(nl80211_attrs name) const;
151
152 // Returns a string describing a given attribute name.
153 static std::string StringFromAttributeName(nl80211_attrs name);
154
155 // Stringizes the MAC address found in 'arg'. If there are problems (such
156 // as a NULL |arg|), |value| is set to a bogus MAC address.
157 static std::string StringFromMacAddress(const uint8_t *arg);
158
Wade Guthried4977f22012-08-22 12:37:54 -0700159 // Returns a string representing the passed-in |status| or |reason|, the
160 // value of which has been acquired from libnl (for example, from the
Wade Guthrie0d438532012-05-18 14:18:50 -0700161 // NL80211_ATTR_STATUS_CODE or NL80211_ATTR_REASON_CODE attribute).
Wade Guthried4977f22012-08-22 12:37:54 -0700162 static std::string StringFromReason(uint16_t reason);
Wade Guthrie0d438532012-05-18 14:18:50 -0700163 static std::string StringFromStatus(uint16_t status);
164
165 // Returns a string that describes this message.
166 virtual std::string ToString() const { return GetHeaderString(); }
167
168 protected:
169 // Duplicate attribute data, store in map indexed on 'name'.
170 bool AddAttribute(nl80211_attrs name, nlattr *data);
171
172 // Returns the raw nlattr for a given attribute (NULL if attribute doesn't
173 // exist).
174 const nlattr *GetAttribute(nl80211_attrs name) const;
175
176 // Returns a string that should precede all user-bound message strings.
177 virtual std::string GetHeaderString() const;
178
179 // Returns a string that describes the contents of the frame pointed to by
180 // 'attr'.
181 std::string StringFromFrame(nl80211_attrs attr_name) const;
182
183 // Converts key_type to a string.
184 static std::string StringFromKeyType(nl80211_key_type key_type);
185
186 // Returns a string representation of the REG initiator described by the
187 // method's parameter.
188 static std::string StringFromRegInitiator(__u8 initiator);
189
190 // Returns a string based on the SSID found in 'data'. Non-printable
191 // characters are string-ized.
192 static std::string StringFromSsid(const uint8_t len, const uint8_t *data);
193
194 private:
195 friend class AttributeNameIterator;
196 friend class Config80211Test;
197 FRIEND_TEST(Config80211Test, NL80211_CMD_NOTIFY_CQM);
198
199 static const uint32_t kIllegalMessage;
200 static const int kEthernetAddressBytes;
201
202 nlmsghdr *message_;
Wade Guthried4977f22012-08-22 12:37:54 -0700203 static std::map<uint16_t, std::string> *reason_code_string_;
204 static std::map<uint16_t, std::string> *status_code_string_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700205 std::map<nl80211_attrs, nlattr *> attributes_;
206
207 DISALLOW_COPY_AND_ASSIGN(UserBoundNlMessage);
208};
209
210class Nl80211Frame {
211 public:
212 enum Type {
213 kAssocResponseFrameType = 0x10,
214 kReassocResponseFrameType = 0x30,
215 kAssocRequestFrameType = 0x00,
216 kReassocRequestFrameType = 0x20,
217 kAuthFrameType = 0xb0,
218 kDisassocFrameType = 0xa0,
219 kDeauthFrameType = 0xc0,
220 kIllegalFrameType = 0xff
221 };
222
223 Nl80211Frame(const uint8_t *frame, int frame_byte_count);
224 ~Nl80211Frame();
Wade Guthried4977f22012-08-22 12:37:54 -0700225 bool ToString(std::string *output) const;
226 bool IsEqual(const Nl80211Frame &other) const;
227 uint16_t reason() const { return reason_; }
228 uint16_t status() const { return status_; }
Wade Guthrie0d438532012-05-18 14:18:50 -0700229
230 private:
231 static const uint8_t kMinimumFrameByteCount;
232 static const uint8_t kFrameTypeMask;
233
234 std::string mac_from_;
235 std::string mac_to_;
236 uint8_t frame_type_;
Wade Guthried4977f22012-08-22 12:37:54 -0700237 uint16_t reason_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700238 uint16_t status_;
239 uint8_t *frame_;
240 int byte_count_;
241
242 DISALLOW_COPY_AND_ASSIGN(Nl80211Frame);
243};
244
245//
246// Specific UserBoundNlMessage types.
247//
248
249class AssociateMessage : public UserBoundNlMessage {
250 public:
251 static const uint8_t kCommand;
252 static const char kCommandString[];
253
254 AssociateMessage() {}
255
256 virtual uint8_t GetMessageType() const { return AssociateMessage::kCommand; }
257 virtual std::string GetMessageTypeString() const {
258 return AssociateMessage::kCommandString;
259 }
260 virtual std::string ToString() const;
261
262 private:
263 DISALLOW_COPY_AND_ASSIGN(AssociateMessage);
264};
265
266
267class AuthenticateMessage : public UserBoundNlMessage {
268 public:
269 static const uint8_t kCommand;
270 static const char kCommandString[];
271
272 AuthenticateMessage() {}
273
274 virtual uint8_t GetMessageType() const {
275 return AuthenticateMessage::kCommand;
276 }
277 virtual std::string GetMessageTypeString() const {
278 return AuthenticateMessage::kCommandString;
279 }
280 virtual std::string ToString() const;
281
282 private:
283 DISALLOW_COPY_AND_ASSIGN(AuthenticateMessage);
284};
285
286
287class CancelRemainOnChannelMessage : public UserBoundNlMessage {
288 public:
289 static const uint8_t kCommand;
290 static const char kCommandString[];
291
292 CancelRemainOnChannelMessage() {}
293
294 virtual uint8_t GetMessageType() const {
295 return CancelRemainOnChannelMessage::kCommand;
296 }
297 virtual std::string GetMessageTypeString() const {
298 return CancelRemainOnChannelMessage::kCommandString;
299 }
300 virtual std::string ToString() const;
301
302 private:
303 DISALLOW_COPY_AND_ASSIGN(CancelRemainOnChannelMessage);
304};
305
306
307class ConnectMessage : public UserBoundNlMessage {
308 public:
309 static const uint8_t kCommand;
310 static const char kCommandString[];
311
312 ConnectMessage() {}
313
314 virtual uint8_t GetMessageType() const { return ConnectMessage::kCommand; }
315 virtual std::string GetMessageTypeString() const {
316 return ConnectMessage::kCommandString;
317 }
318 virtual std::string ToString() const;
319
320 private:
321 DISALLOW_COPY_AND_ASSIGN(ConnectMessage);
322};
323
324
325class DeauthenticateMessage : public UserBoundNlMessage {
326 public:
327 static const uint8_t kCommand;
328 static const char kCommandString[];
329
330 DeauthenticateMessage() {}
331
332 virtual uint8_t GetMessageType() const {
333 return DeauthenticateMessage::kCommand;
334 }
335 virtual std::string GetMessageTypeString() const {
336 return DeauthenticateMessage::kCommandString;
337 }
338 virtual std::string ToString() const;
339
340 private:
341 DISALLOW_COPY_AND_ASSIGN(DeauthenticateMessage);
342};
343
344
345class DeleteStationMessage : public UserBoundNlMessage {
346 public:
347 static const uint8_t kCommand;
348 static const char kCommandString[];
349
350 DeleteStationMessage() {}
351
352 virtual uint8_t GetMessageType() const {
353 return DeleteStationMessage::kCommand;
354 }
355 virtual std::string GetMessageTypeString() const {
356 return DeleteStationMessage::kCommandString;
357 }
358 virtual std::string ToString() const;
359
360 private:
361 DISALLOW_COPY_AND_ASSIGN(DeleteStationMessage);
362};
363
364
365class DisassociateMessage : public UserBoundNlMessage {
366 public:
367 static const uint8_t kCommand;
368 static const char kCommandString[];
369
370 DisassociateMessage() {}
371
372 virtual uint8_t GetMessageType() const {
373 return DisassociateMessage::kCommand;
374 }
375 virtual std::string GetMessageTypeString() const {
376 return DisassociateMessage::kCommandString;
377 }
378 virtual std::string ToString() const;
379
380 private:
381 DISALLOW_COPY_AND_ASSIGN(DisassociateMessage);
382};
383
384
385class DisconnectMessage : public UserBoundNlMessage {
386 public:
387 static const uint8_t kCommand;
388 static const char kCommandString[];
389
390 DisconnectMessage() {}
391
392 virtual uint8_t GetMessageType() const { return DisconnectMessage::kCommand; }
393 virtual std::string GetMessageTypeString() const {
394 return DisconnectMessage::kCommandString;
395 }
396 virtual std::string ToString() const;
397
398 private:
399 DISALLOW_COPY_AND_ASSIGN(DisconnectMessage);
400};
401
402
403class FrameTxStatusMessage : public UserBoundNlMessage {
404 public:
405 static const uint8_t kCommand;
406 static const char kCommandString[];
407
408 FrameTxStatusMessage() {}
409
410 virtual uint8_t GetMessageType() const {
411 return FrameTxStatusMessage::kCommand;
412 }
413 virtual std::string GetMessageTypeString() const {
414 return FrameTxStatusMessage::kCommandString;
415 }
416 virtual std::string ToString() const;
417
418 private:
419 DISALLOW_COPY_AND_ASSIGN(FrameTxStatusMessage);
420};
421
422
423class JoinIbssMessage : public UserBoundNlMessage {
424 public:
425 static const uint8_t kCommand;
426 static const char kCommandString[];
427
428 JoinIbssMessage() {}
429
430 virtual uint8_t GetMessageType() const { return JoinIbssMessage::kCommand; }
431 virtual std::string GetMessageTypeString() const {
432 return JoinIbssMessage::kCommandString;
433 }
434 virtual std::string ToString() const;
435
436 private:
437 DISALLOW_COPY_AND_ASSIGN(JoinIbssMessage);
438};
439
440
441class MichaelMicFailureMessage : public UserBoundNlMessage {
442 public:
443 static const uint8_t kCommand;
444 static const char kCommandString[];
445
446 MichaelMicFailureMessage() {}
447
448 virtual uint8_t GetMessageType() const {
449 return MichaelMicFailureMessage::kCommand;
450 }
451 virtual std::string GetMessageTypeString() const {
452 return MichaelMicFailureMessage::kCommandString;
453 }
454 virtual std::string ToString() const;
455
456 private:
457 DISALLOW_COPY_AND_ASSIGN(MichaelMicFailureMessage);
458};
459
460
461class NewScanResultsMessage : public UserBoundNlMessage {
462 public:
463 static const uint8_t kCommand;
464 static const char kCommandString[];
465
466 NewScanResultsMessage() {}
467
468 virtual uint8_t GetMessageType() const {
469 return NewScanResultsMessage::kCommand;
470 }
471 virtual std::string GetMessageTypeString() const {
472 return NewScanResultsMessage::kCommandString;
473 }
474 virtual std::string ToString() const;
475
476 private:
477 DISALLOW_COPY_AND_ASSIGN(NewScanResultsMessage);
478};
479
480
481class NewStationMessage : public UserBoundNlMessage {
482 public:
483 static const uint8_t kCommand;
484 static const char kCommandString[];
485
486 NewStationMessage() {}
487
488 virtual uint8_t GetMessageType() const { return NewStationMessage::kCommand; }
489 virtual std::string GetMessageTypeString() const {
490 return NewStationMessage::kCommandString;
491 }
492 virtual std::string ToString() const;
493
494 private:
495 DISALLOW_COPY_AND_ASSIGN(NewStationMessage);
496};
497
498
499class NewWifiMessage : public UserBoundNlMessage {
500 public:
501 static const uint8_t kCommand;
502 static const char kCommandString[];
503
504 NewWifiMessage() {}
505
506 virtual uint8_t GetMessageType() const { return NewWifiMessage::kCommand; }
507 virtual std::string GetMessageTypeString() const {
508 return NewWifiMessage::kCommandString;
509 }
510 virtual std::string ToString() const;
511
512 private:
513 DISALLOW_COPY_AND_ASSIGN(NewWifiMessage);
514};
515
516
517class NotifyCqmMessage : public UserBoundNlMessage {
518 public:
519 static const uint8_t kCommand;
520 static const char kCommandString[];
521
522 NotifyCqmMessage() {}
523
524 virtual uint8_t GetMessageType() const { return NotifyCqmMessage::kCommand; }
525 virtual std::string GetMessageTypeString() const {
526 return NotifyCqmMessage::kCommandString;
527 }
528 virtual std::string ToString() const;
529
530 private:
531 DISALLOW_COPY_AND_ASSIGN(NotifyCqmMessage);
532};
533
534
535class PmksaCandidateMessage : public UserBoundNlMessage {
536 public:
537 static const uint8_t kCommand;
538 static const char kCommandString[];
539
540 PmksaCandidateMessage() {}
541
542 virtual uint8_t GetMessageType() const {
543 return PmksaCandidateMessage::kCommand;
544 }
545 virtual std::string GetMessageTypeString() const {
546 return PmksaCandidateMessage::kCommandString;
547 }
548 virtual std::string ToString() const;
549
550 private:
551 DISALLOW_COPY_AND_ASSIGN(PmksaCandidateMessage);
552};
553
554
555class RegBeaconHintMessage : public UserBoundNlMessage {
556 public:
557 static const uint8_t kCommand;
558 static const char kCommandString[];
559
560 RegBeaconHintMessage() {}
561
562 virtual uint8_t GetMessageType() const {
563 return RegBeaconHintMessage::kCommand;
564 }
565 virtual std::string GetMessageTypeString() const {
566 return RegBeaconHintMessage::kCommandString;
567 }
568 virtual std::string ToString() const;
569
570 private:
571 struct ieee80211_beacon_channel {
572 __u16 center_freq;
573 bool passive_scan;
574 bool no_ibss;
575 };
576
577 // Returns the channel ID calculated from the 802.11 frequency.
578 static int ChannelFromIeee80211Frequency(int freq);
579
580 // Sets values in |chan| based on attributes in |tb|, the array of pointers
581 // to netlink attributes, indexed by attribute type.
582 int ParseBeaconHintChan(const nlattr *tb,
583 ieee80211_beacon_channel *chan) const;
584
585 DISALLOW_COPY_AND_ASSIGN(RegBeaconHintMessage);
586};
587
588
589class RegChangeMessage : public UserBoundNlMessage {
590 public:
591 static const uint8_t kCommand;
592 static const char kCommandString[];
593
594 RegChangeMessage() {}
595
596 virtual uint8_t GetMessageType() const { return RegChangeMessage::kCommand; }
597 virtual std::string GetMessageTypeString() const {
598 return RegChangeMessage::kCommandString;
599 }
600 virtual std::string ToString() const;
601
602 private:
603 DISALLOW_COPY_AND_ASSIGN(RegChangeMessage);
604};
605
606
607class RemainOnChannelMessage : public UserBoundNlMessage {
608 public:
609 static const uint8_t kCommand;
610 static const char kCommandString[];
611
612 RemainOnChannelMessage() {}
613
614 virtual uint8_t GetMessageType() const {
615 return RemainOnChannelMessage::kCommand;
616 }
617 virtual std::string GetMessageTypeString() const {
618 return RemainOnChannelMessage::kCommandString;
619 }
620 virtual std::string ToString() const;
621
622 private:
623 DISALLOW_COPY_AND_ASSIGN(RemainOnChannelMessage);
624};
625
626
627class RoamMessage : public UserBoundNlMessage {
628 public:
629 static const uint8_t kCommand;
630 static const char kCommandString[];
631
632 RoamMessage() {}
633
634 virtual uint8_t GetMessageType() const { return RoamMessage::kCommand; }
635 virtual std::string GetMessageTypeString() const {
636 return RoamMessage::kCommandString;
637 }
638 virtual std::string ToString() const;
639
640 private:
641 DISALLOW_COPY_AND_ASSIGN(RoamMessage);
642};
643
644
645class ScanAbortedMessage : public UserBoundNlMessage {
646 public:
647 static const uint8_t kCommand;
648 static const char kCommandString[];
649
650 ScanAbortedMessage() {}
651
652 virtual uint8_t GetMessageType() const {
653 return ScanAbortedMessage::kCommand;
654 }
655 virtual std::string GetMessageTypeString() const {
656 return ScanAbortedMessage::kCommandString;
657 }
658 virtual std::string ToString() const;
659
660 private:
661 DISALLOW_COPY_AND_ASSIGN(ScanAbortedMessage);
662};
663
664
665class TriggerScanMessage : public UserBoundNlMessage {
666 public:
667 static const uint8_t kCommand;
668 static const char kCommandString[];
669
670 TriggerScanMessage() {}
671
672 virtual uint8_t GetMessageType() const {
673 return TriggerScanMessage::kCommand;
674 }
675 virtual std::string GetMessageTypeString() const {
676 return TriggerScanMessage::kCommandString;
677 }
678 virtual std::string ToString() const;
679
680 private:
681 DISALLOW_COPY_AND_ASSIGN(TriggerScanMessage);
682};
683
684
685class UnknownMessage : public UserBoundNlMessage {
686 public:
687 explicit UnknownMessage(uint8_t command) : command_(command) {}
688
689 static const uint8_t kCommand;
690 static const char kCommandString[];
691
692 virtual uint8_t GetMessageType() const { return command_; }
693 virtual std::string GetMessageTypeString() const {
694 return UnknownMessage::kCommandString;
695 }
696 virtual std::string ToString() const;
697
698 private:
699 uint8_t command_;
700
701 DISALLOW_COPY_AND_ASSIGN(UnknownMessage);
702};
703
704
705class UnprotDeauthenticateMessage : public UserBoundNlMessage {
706 public:
707 static const uint8_t kCommand;
708 static const char kCommandString[];
709
710 UnprotDeauthenticateMessage() {}
711
712 virtual uint8_t GetMessageType() const {
713 return UnprotDeauthenticateMessage::kCommand;
714 }
715 virtual std::string GetMessageTypeString() const {
716 return UnprotDeauthenticateMessage::kCommandString;
717 }
718 virtual std::string ToString() const;
719
720 private:
721 DISALLOW_COPY_AND_ASSIGN(UnprotDeauthenticateMessage);
722};
723
724
725class UnprotDisassociateMessage : public UserBoundNlMessage {
726 public:
727 static const uint8_t kCommand;
728 static const char kCommandString[];
729
730 UnprotDisassociateMessage() {}
731
732 virtual uint8_t GetMessageType() const {
733 return UnprotDisassociateMessage::kCommand;
734 }
735 virtual std::string GetMessageTypeString() const {
736 return UnprotDisassociateMessage::kCommandString;
737 }
738 virtual std::string ToString() const;
739
740 private:
741 DISALLOW_COPY_AND_ASSIGN(UnprotDisassociateMessage);
742};
743
744
745//
746// Factory class.
747//
748
749class UserBoundNlMessageFactory {
750 public:
751 // Ownership of the message is passed to the caller and, as such, he should
752 // delete it.
753 static UserBoundNlMessage *CreateMessage(nlmsghdr *msg);
754
755 private:
756 DISALLOW_COPY_AND_ASSIGN(UserBoundNlMessageFactory);
757};
758
759
760// UserBoundNlMessageDataCollector - this class is used to collect data to be
761// used for unit tests. It is only invoked in this case.
762
763class UserBoundNlMessageDataCollector {
764 public:
765 // This is a singleton -- use Config80211::GetInstance()->Foo()
766 static UserBoundNlMessageDataCollector *GetInstance();
767
768 void CollectDebugData(const UserBoundNlMessage &message, nlmsghdr *msg);
769
770 protected:
771 friend struct
772 base::DefaultLazyInstanceTraits<UserBoundNlMessageDataCollector>;
773
774 explicit UserBoundNlMessageDataCollector();
775
776 private:
777 // In order to limit the output from this class, I keep track of types I
778 // haven't yet printed.
779 std::map<uint8_t, bool> need_to_print;
780};
781
782} // namespace shill
783
784#endif // SHILL_USER_BOUND_NLMESSAGE_H_