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_ATTRIBUTE_LIST_H_
18 #define SHILL_NET_ATTRIBUTE_LIST_H_
19 
20 #include <linux/nl80211.h>
21 
22 #include <map>
23 #include <memory>
24 #include <string>
25 
26 #include <base/bind.h>
27 
28 #include "shill/net/netlink_message.h"
29 #include "shill/net/shill_export.h"
30 
31 struct nlattr;
32 namespace shill {
33 
34 class AttributeList;
35 typedef scoped_refptr<const AttributeList> AttributeListConstRefPtr;
36 typedef scoped_refptr<AttributeList> AttributeListRefPtr;
37 
38 class ByteString;
39 class NetlinkAttribute;
40 class NetlinkRawAttribute;
41 
42 class SHILL_EXPORT AttributeList : public base::RefCounted<AttributeList> {
43  public:
44   using AttributePointer = std::shared_ptr<NetlinkAttribute>;
45   using NewFromIdMethod = base::Callback<NetlinkAttribute*(int id)>;
46   using AttributeMethod = base::Callback<bool(int id, const ByteString& value)>;
47 
AttributeList()48   AttributeList() {}
49 
50   // Instantiates an NetlinkAttribute of the appropriate type from |id|,
51   // and adds it to |attributes_|.
52   bool CreateAttribute(int id, NewFromIdMethod factory);
53 
54   // Helper function for creating control attribute.
55   bool CreateControlAttribute(int id);
56 
57   // Helper function for creating nl80211 attribute.
58   bool CreateNl80211Attribute(int id, NetlinkMessage::MessageContext context);
59 
60   // Instantiates an NetlinkAttribute of the appropriate type from |id|
61   // using |factory|, initializes it from |value|, and adds it to |attributes_|.
62   bool CreateAndInitAttribute(const NewFromIdMethod& factory,
63                               int id, const ByteString& value);
64 
65   // Initializes the attribute |id| from the data in |value|.
66   bool InitAttributeFromValue(int id, const ByteString& value);
67 
68   // Prints the attribute list with each attribute using no less than 1 line.
69   // |indent| indicates the amout of leading spaces to be printed (useful for
70   // nested attributes).
71   void Print(int log_level, int indent) const;
72 
73   // Visit each attribute in |payload| starting at |offset|.  Call |method|
74   // for each attribute.  If |method| returns false, the travesal is terminated
75   // and false is returned.  If a malformed attribute entry is encountered,
76   // this method also returns false.
77   static bool IterateAttributes(const ByteString& payload, size_t offset,
78                                 const AttributeMethod& method);
79 
80   // Decode an attribute list starting from |offset| within |payload|.  Use
81   // |factory| to create each attribute object.
82   bool Decode(const ByteString& payload,
83               size_t offset, const NewFromIdMethod& factory);
84 
85   // Returns the attributes as the payload portion of a netlink message
86   // suitable for Sockets::Send.  Return value is empty on failure (or if no
87   // attributes exist).
88   ByteString Encode() const;
89 
90   // Create, get, and set attributes of the given types.  Attributes are
91   // accessed via an integer |id|.  |id_string| is a string used to describe
92   // the attribute in debug output.
93   bool CreateU8Attribute(int id, const char* id_string);
94   bool SetU8AttributeValue(int id, uint8_t value);
95   bool GetU8AttributeValue(int id, uint8_t* value) const;
96 
97   bool CreateU16Attribute(int id, const char* id_string);
98   bool SetU16AttributeValue(int id, uint16_t value);
99   bool GetU16AttributeValue(int id, uint16_t* value) const;
100 
101   bool CreateU32Attribute(int id, const char* id_string);
102   bool SetU32AttributeValue(int id, uint32_t value);
103   bool GetU32AttributeValue(int id, uint32_t* value) const;
104 
105   bool CreateU64Attribute(int id, const char* id_string);
106   bool SetU64AttributeValue(int id, uint64_t value);
107   bool GetU64AttributeValue(int id, uint64_t* value) const;
108 
109   bool CreateFlagAttribute(int id, const char* id_string);
110   bool SetFlagAttributeValue(int id, bool value);
111   bool GetFlagAttributeValue(int id, bool* value) const;
112   // |IsFlagAttributeTrue| returns true if the flag attribute |id| is true.  It
113   // retruns false if the attribute does not exist, is not of type kTypeFlag,
114   // or is not true.
115   bool IsFlagAttributeTrue(int id) const;
116 
117   bool CreateStringAttribute(int id, const char* id_string);
118   // SSID attributes are derived from string attributes.
119   bool CreateSsidAttribute(int id, const char* id_string);
120   bool SetStringAttributeValue(int id, std::string value);
121   bool GetStringAttributeValue(int id, std::string* value) const;
122 
123   bool CreateNestedAttribute(int id, const char* id_string);
124   bool SetNestedAttributeHasAValue(int id);
125   bool GetNestedAttributeList(int id, AttributeListRefPtr* value);
126   bool ConstGetNestedAttributeList(int id,
127                                    AttributeListConstRefPtr* value) const;
128 
129   bool CreateRawAttribute(int id, const char* id_string);
130   // |value| should point to the data (after the |nlattr| header, if there is
131   // one).
132   bool SetRawAttributeValue(int id, ByteString value);
133   bool GetRawAttributeValue(int id, ByteString* output) const;
134 
135   // This retrieves a string from any kind of attribute.
136   bool GetAttributeAsString(int id, std::string* value) const;
137 
138  protected:
139   friend class base::RefCounted<AttributeList>;
~AttributeList()140   virtual ~AttributeList() {}
141 
142  private:
143   typedef std::map<int, AttributePointer> AttributeMap;
144   friend class AttributeIdIterator;
145   friend class NetlinkNestedAttribute;
146 
147   // Using this to get around issues with const and operator[].
148   SHILL_PRIVATE NetlinkAttribute* GetAttribute(int id) const;
149 
150   AttributeMap attributes_;
151 
152   DISALLOW_COPY_AND_ASSIGN(AttributeList);
153 };
154 
155 // Provides a mechanism to iterate through the ids of all of the attributes
156 // in an |AttributeList|.  This class is really only useful if the caller
157 // knows the type of each attribute in advance (such as with a nested array).
158 class AttributeIdIterator {
159  public:
AttributeIdIterator(const AttributeList & list)160   explicit AttributeIdIterator(const AttributeList& list)
161       : iter_(list.attributes_.begin()),
162         end_(list.attributes_.end()) {
163   }
Advance()164   void Advance() { ++iter_; }
AtEnd()165   bool AtEnd() const { return iter_ == end_; }
GetId()166   int GetId() const { return iter_->first; }
167 
168  private:
169   AttributeList::AttributeMap::const_iterator iter_;
170   const AttributeList::AttributeMap::const_iterator end_;
171 
172   DISALLOW_COPY_AND_ASSIGN(AttributeIdIterator);
173 };
174 
175 }  // namespace shill
176 
177 #endif  // SHILL_NET_ATTRIBUTE_LIST_H_
178