blob: 9ead8ee7365408819b38ce8400792c41c63f7b16 [file] [log] [blame]
Wade Guthrie16196242012-11-20 15:53:52 -08001// 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_NLATTRIBUTE_H_
6#define SHILL_NLATTRIBUTE_H_
7
8#include <linux/nl80211.h>
9#include <netlink/netlink.h>
10
11#include <map>
12#include <string>
13
14#include <base/memory/scoped_ptr.h>
15
16#include "shill/byte_string.h"
17
18struct nlattr;
19
20namespace shill {
21
22// Nl80211Attribute is an abstract base class that describes an attribute in a
23// netlink-80211 message. Child classes are type-specific and will define
24// Get*Value and Set*Value methods (where * is the type). A second-level of
25// child classes exist for each individual attribute type.
26//
27// An attribute has a name (which is really an enumerated value), a data type,
28// and a value. In an nlattr (the underlying format for an attribute in a
29// message), the data is stored as a blob without type information; the writer
30// and reader of the attribute must agree on the data type.
31class Nl80211Attribute {
32 public:
33 enum Type {
34 kTypeU8,
35 kTypeU16,
36 kTypeU32,
37 kTypeU64,
38 kTypeString,
39 kTypeFlag,
40 kTypeMsecs,
41 kTypeNested,
42 kTypeRaw,
43 kTypeError
44 };
45
46 Nl80211Attribute(nl80211_attrs name, const char *name_string,
47 Type type, const char *type_string);
48 virtual ~Nl80211Attribute() {}
49
50 virtual bool InitFromNlAttr(const nlattr *data);
51
52 // Static factory generates the appropriate Nl80211Attribute object from the
53 // raw nlattr data.
54 static Nl80211Attribute *NewFromNlAttr(nl80211_attrs name,
55 const nlattr *data);
56
57 // Accessors for the attribute's name and type information.
58 nl80211_attrs name() const { return name_; }
59 virtual const char *name_string() const { return name_string_; }
60 Type type() const { return type_; }
61 std::string type_string() const { return type_string_; }
62
63 // TODO(wdg): Since |data| is used, externally, to support |nla_parse_nested|,
64 // make it protected once all functionality has been brought inside the
65 // Nl80211Attribute classes.
66 //
67 // |data_| contains an 'nlattr *' but it's been stored as a ByteString.
68 // This returns a pointer to the data in the form that is intended.
69 const nlattr *data() const {
70 return reinterpret_cast<const nlattr *>(data_.GetConstData());
71 }
72
73 // TODO(wdg): GetRawData is used to support
74 // UserBoundNlMessage::GetRawAttributeData which, in turn, is used to support
75 // NL80211_ATTR_FRAME and NL80211_ATTR_KEY_SEQ. Remove this method (and that
76 // one) once those classes are fleshed-out.
77 //
78 // If successful, returns 'true' and sets *|value| to the raw attribute data
79 // (after the header) for this attribute. Otherwise, returns 'false' and
80 // leaves |value| unchanged.
81 bool GetRawData(ByteString *value) const;
82
83 // Fill a string with characters that represents the value of the attribute.
84 // If no attribute is found or if the type isn't trivially stringizable,
85 // this method returns 'false' and |value| remains unchanged.
86 virtual bool AsString(std::string *value) const = 0;
87
88 // Writes the raw attribute data to a string. For debug.
89 std::string RawToString() const;
90
91 protected:
92 // Raw data corresponding to the value in any of the child classes.
93 // TODO(wdg): When 'data()' is removed, move this to the Nl80211RawAttribute
94 // class.
95 ByteString data_;
96
97 private:
98 nl80211_attrs name_;
99 const char *name_string_;
100 Type type_;
101 const char *type_string_;
102};
103
104// Type-specific sub-classes. These provide their own type-specific data get
105// and set functions.
106
107class Nl80211U32Attribute : public Nl80211Attribute {
108 public:
109 static const char kMyTypeString[];
110 static const Type kType;
111 Nl80211U32Attribute(nl80211_attrs name, const char *name_string)
112 : Nl80211Attribute(name, name_string, kType, kMyTypeString) {}
113 bool InitFromNlAttr(const nlattr *data);
114 bool GetU32Value(uint32_t *value) const;
115 bool SetU32Value(uint32_t new_value);
116 bool AsString(std::string *value) const;
117
118 private:
119 uint32_t value_;
120};
121
122// TODO(wdg): Add more data types.
123
124class Nl80211RawAttribute : public Nl80211Attribute {
125 public:
126 static const char kMyTypeString[];
127 static const Type kType;
128 Nl80211RawAttribute(nl80211_attrs name, const char *name_string)
129 : Nl80211Attribute(name, name_string, kType, kMyTypeString) {}
130 bool InitFromNlAttr(const nlattr *data);
131 bool GetRawValue(const ByteString **value) const;
132 // Not supporting 'set' for raw data. This type is a "don't know" type to
133 // be used for user-bound massages (via InitFromNlAttr). The 'set' method
134 // is intended for building kernel-bound messages and shouldn't be used with
135 // raw data.
136 bool AsString(std::string *value) const;
137};
138
139// Attribute-specific sub-classes.
140
141class Nl80211AttributeDuration : public Nl80211U32Attribute {
142 public:
143 static const nl80211_attrs kName;
144 static const char kNameString[];
145 explicit Nl80211AttributeDuration()
146 : Nl80211U32Attribute(kName, kNameString) {}
147};
148
149class Nl80211AttributeGeneric : public Nl80211RawAttribute {
150 public:
151 explicit Nl80211AttributeGeneric(nl80211_attrs name);
152 const char *name_string() const;
153
154 private:
155 std::string name_string_;
156};
157
158} // namespace shill
159
160#endif // SHILL_NLATTRIBUTE_H_