blob: 44753bcb8dc8e32db0f7deffab2a10cb2a44cae6 [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#include "shill/nl80211_attribute.h"
6
7#include <ctype.h>
8#include <linux/nl80211.h>
9#include <netlink/attr.h>
10#include <netlink/netlink.h>
11
12#include <iomanip>
13#include <string>
14
15#include <base/format_macros.h>
16#include <base/stl_util.h>
17#include <base/stringprintf.h>
18
19#include "shill/logging.h"
20#include "shill/scope_logger.h"
21
22using std::string;
23
24using base::StringAppendF;
25using base::StringPrintf;
26
27namespace shill {
28
29Nl80211Attribute::Nl80211Attribute(enum nl80211_attrs name,
30 const char *name_string,
31 Type type,
32 const char *type_string)
33 : name_(name), name_string_(name_string), type_(type),
34 type_string_(type_string) {}
35
36// static
37Nl80211Attribute *Nl80211Attribute::NewFromNlAttr(nl80211_attrs name,
38 const nlattr *data) {
39 scoped_ptr<Nl80211Attribute> attr;
40 switch (name) {
41 case NL80211_ATTR_DURATION:
42 attr.reset(new Nl80211AttributeDuration());
43 break;
44
45 // TODO(wdg): Add more attributes.
46
47 default:
48 attr.reset(new Nl80211AttributeGeneric(name));
49 break;
50 }
51 attr->InitFromNlAttr(data);
52 return attr.release();
53}
54
55// Duplicate attribute data, store in map indexed on |name|.
56bool Nl80211Attribute::InitFromNlAttr(const nlattr *other) {
57 if (!other) {
58 LOG(ERROR) << "NULL data";
59 return false;
60 }
61
62 data_ = ByteString(reinterpret_cast<const unsigned char *>(other),
63 nla_total_size(nla_len(const_cast<nlattr *>(other))));
64 return true;
65}
66
Wade Guthrie8343f7f2012-12-04 13:52:32 -080067// Copies raw attribute data but not the header.
Wade Guthrie16196242012-11-20 15:53:52 -080068bool Nl80211Attribute::GetRawData(ByteString *output) const {
69 if (!output) {
70 LOG(ERROR) << "Null |output| parameter";
71 return false;
72 }
73
74 *output = data_;
75 return true;
76}
77
78string Nl80211Attribute::RawToString() const {
79 string output = " === RAW: ";
80
81 nlattr *data_nlattr = const_cast<nlattr *>(data());
82 uint16_t length = nla_len(data_nlattr);
83 StringAppendF(&output, "len=%u", length);
84
85 const uint8_t *const_data = reinterpret_cast<const uint8_t *>(data());
86
87 output.append(" DATA: ");
88 for (int i =0 ; i < length; ++i) {
89 StringAppendF(&output, "[%d]=%02x ", i, *(const_data)+i);
90 }
91 output.append(" ==== ");
92 return output;
93}
94
Wade Guthrie8343f7f2012-12-04 13:52:32 -080095// Nl80211U8Attribute
96
97const char Nl80211U8Attribute::kMyTypeString[] = "uint8_t";
98const Nl80211Attribute::Type Nl80211U8Attribute::kType =
99 Nl80211Attribute::kTypeU8;
100
101bool Nl80211U8Attribute::InitFromNlAttr(const nlattr *input) {
102 if (!input) {
103 LOG(ERROR) << "Null |input| parameter";
104 return false;
105 }
106
107 uint8_t data = NlaGetU8(input);
108 SetU8Value(data);
109 return Nl80211Attribute::InitFromNlAttr(input);
110}
111
112bool Nl80211U8Attribute::GetU8Value(uint8_t *output) const {
113 if (!output) {
114 LOG(ERROR) << "Null |output| parameter";
115 return false;
116 }
117 *output = value_;
118 return true;
119}
120
121bool Nl80211U8Attribute::SetU8Value(uint8_t new_value) {
122 value_ = new_value;
123 return true;
124}
125
126bool Nl80211U8Attribute::AsString(string *output) const {
127 if (!output) {
128 LOG(ERROR) << "Null |output| parameter";
129 return false;
130 }
131 uint8_t value;
132 if (!GetU8Value(&value))
133 return false;
134 *output = StringPrintf("%u", value);
135 return true;
136}
137
138
139// Nl80211U16Attribute
140
141const char Nl80211U16Attribute::kMyTypeString[] = "uint16_t";
142const Nl80211Attribute::Type Nl80211U16Attribute::kType =
143 Nl80211Attribute::kTypeU16;
144
145bool Nl80211U16Attribute::InitFromNlAttr(const nlattr *input) {
146 if (!input) {
147 LOG(ERROR) << "Null |input| parameter";
148 return false;
149 }
150
151 uint16_t data = NlaGetU16(input);
152 SetU16Value(data);
153 return Nl80211Attribute::InitFromNlAttr(input);
154}
155
156bool Nl80211U16Attribute::GetU16Value(uint16_t *output) const {
157 if (!output) {
158 LOG(ERROR) << "Null |output| parameter";
159 return false;
160 }
161 *output = value_;
162 return true;
163}
164
165bool Nl80211U16Attribute::SetU16Value(uint16_t new_value) {
166 value_ = new_value;
167 return true;
168}
169
170bool Nl80211U16Attribute::AsString(string *output) const {
171 if (!output) {
172 LOG(ERROR) << "Null |output| parameter";
173 return false;
174 }
175 uint16_t value;
176 if (!GetU16Value(&value))
177 return false;
178 *output = StringPrintf("%u", value);
179 return true;
180}
181
Wade Guthrie16196242012-11-20 15:53:52 -0800182// Nl80211U32Attribute::
183
184const char Nl80211U32Attribute::kMyTypeString[] = "uint32_t";
185const Nl80211Attribute::Type Nl80211U32Attribute::kType =
186 Nl80211Attribute::kTypeU32;
187
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800188bool Nl80211U32Attribute::InitFromNlAttr(const nlattr *input) {
189 if (!input) {
190 LOG(ERROR) << "Null |input| parameter";
Wade Guthrie16196242012-11-20 15:53:52 -0800191 return false;
192 }
193
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800194 uint32_t data = NlaGetU32(input);
Wade Guthrie16196242012-11-20 15:53:52 -0800195 SetU32Value(data);
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800196 return Nl80211Attribute::InitFromNlAttr(input);
Wade Guthrie16196242012-11-20 15:53:52 -0800197}
198
199bool Nl80211U32Attribute::GetU32Value(uint32_t *output) const {
200 if (!output) {
201 LOG(ERROR) << "Null |output| parameter";
202 return false;
203 }
204 *output = value_;
205 return true;
206}
207
208bool Nl80211U32Attribute::SetU32Value(uint32_t new_value) {
209 value_ = new_value;
210 return true;
211}
212
213bool Nl80211U32Attribute::AsString(string *output) const {
214 if (!output) {
215 LOG(ERROR) << "Null |output| parameter";
216 return false;
217 }
218 uint32_t value;
219 if (!GetU32Value(&value))
220 return false;
221 *output = StringPrintf("%" PRIu32, value);
222 return true;
223}
224
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800225// Nl80211U64Attribute
226
227const char Nl80211U64Attribute::kMyTypeString[] = "uint64_t";
228const Nl80211Attribute::Type Nl80211U64Attribute::kType =
229 Nl80211Attribute::kTypeU64;
230
231bool Nl80211U64Attribute::InitFromNlAttr(const nlattr *input) {
232 if (!input) {
233 LOG(ERROR) << "Null |input| parameter";
234 return false;
235 }
236
237 uint64_t data = NlaGetU64(input);
238 SetU64Value(data);
239 return Nl80211Attribute::InitFromNlAttr(input);
240}
241
242bool Nl80211U64Attribute::GetU64Value(uint64_t *output) const {
243 if (!output) {
244 LOG(ERROR) << "Null |output| parameter";
245 return false;
246 }
247 *output = value_;
248 return true;
249}
250
251bool Nl80211U64Attribute::SetU64Value(uint64_t new_value) {
252 value_ = new_value;
253 return true;
254}
255
256bool Nl80211U64Attribute::AsString(string *output) const {
257 if (!output) {
258 LOG(ERROR) << "Null |output| parameter";
259 return false;
260 }
261 uint64_t value;
262 if (!GetU64Value(&value))
263 return false;
264 *output = StringPrintf("%" PRIu64, value);
265 return true;
266}
267
268// Nl80211FlagAttribute
269
270const char Nl80211FlagAttribute::kMyTypeString[] = "flag";
271const Nl80211Attribute::Type Nl80211FlagAttribute::kType =
272 Nl80211Attribute::kTypeFlag;
273
274bool Nl80211FlagAttribute::InitFromNlAttr(const nlattr *input) {
275 if (!input) {
276 LOG(ERROR) << "Null |input| parameter";
277 return false;
278 }
279
280 // The existence of the parameter means it's true
281 SetFlagValue(true);
282 return Nl80211Attribute::InitFromNlAttr(input);
283}
284
285
286bool Nl80211FlagAttribute::GetFlagValue(bool *output) const {
287 if (!output) {
288 LOG(ERROR) << "Null |output| parameter";
289 return false;
290 }
291 *output = value_;
292 return true;
293}
294
295bool Nl80211FlagAttribute::SetFlagValue(bool new_value) {
296 value_ = new_value;
297 return true;
298}
299
300bool Nl80211FlagAttribute::AsString(string *output) const {
301 if (!output) {
302 LOG(ERROR) << "Null |output| parameter";
303 return false;
304 }
305 bool value;
306 if (!GetFlagValue(&value))
307 return false;
308 *output = StringPrintf("%s", value ? "true" : "false");
309 return true;
310}
311
312// Nl80211StringAttribute
313
314const char Nl80211StringAttribute::kMyTypeString[] = "string";
315const Nl80211Attribute::Type Nl80211StringAttribute::kType =
316 Nl80211Attribute::kTypeString;
317
318bool Nl80211StringAttribute::InitFromNlAttr(const nlattr *input) {
319 if (!input) {
320 LOG(ERROR) << "Null |input| parameter";
321 return false;
322 }
323
324 SetStringValue(NlaGetString(input));
325 return Nl80211Attribute::InitFromNlAttr(input);
326}
327
328bool Nl80211StringAttribute::GetStringValue(string *output) const {
329 if (!output) {
330 LOG(ERROR) << "Null |output| parameter";
331 return false;
332 }
333 *output = value_;
334 return true;
335}
336
337bool Nl80211StringAttribute::SetStringValue(const string new_value) {
338 value_ = new_value;
339 return true;
340}
341
342bool Nl80211StringAttribute::AsString(string *output) const {
343 if (!output) {
344 LOG(ERROR) << "Null |output| parameter";
345 return false;
346 }
347 return GetStringValue(output);
348}
349
350
Wade Guthrie16196242012-11-20 15:53:52 -0800351// Nl80211RawAttribute
352
353const char Nl80211RawAttribute::kMyTypeString[] = "<raw>";
354const Nl80211Attribute::Type Nl80211RawAttribute::kType =
355 Nl80211Attribute::kTypeRaw;
356
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800357bool Nl80211RawAttribute::InitFromNlAttr(const nlattr *input) {
358 if (!input) {
359 LOG(ERROR) << "Null |input| parameter";
Wade Guthrie16196242012-11-20 15:53:52 -0800360 return false;
361 }
362
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800363 return Nl80211Attribute::InitFromNlAttr(input);
Wade Guthrie16196242012-11-20 15:53:52 -0800364}
365
366bool Nl80211RawAttribute::GetRawValue(const ByteString **output) const {
367 if (!output) {
368 LOG(ERROR) << "NULL |output|";
369 return false;
370 }
371 *output = &data_;
372 return true;
373}
374
375bool Nl80211RawAttribute::AsString(string *output) const {
376 if (!output) {
377 LOG(ERROR) << "Null |output| parameter";
378 return false;
379 }
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800380 // TODO(wdg): Make sure that 'data' is valid.
Wade Guthrie16196242012-11-20 15:53:52 -0800381 const uint8_t *raw_data = reinterpret_cast<const uint8_t *>(data());
382 int total_bytes = nla_len(data());
383 *output = StringPrintf("%d bytes:", total_bytes);
384 for (int i = 0; i < total_bytes; ++i) {
385 StringAppendF(output, " 0x%02x", raw_data[i]);
386 }
387 return true;
388}
389
390// Specific Attributes.
391
392const nl80211_attrs Nl80211AttributeDuration::kName = NL80211_ATTR_DURATION;
393const char Nl80211AttributeDuration::kNameString[] = "NL80211_ATTR_DURATION";
394
395Nl80211AttributeGeneric::Nl80211AttributeGeneric(nl80211_attrs name)
396 : Nl80211RawAttribute(name, "unused-string") {
397 StringAppendF(&name_string_, "<UNKNOWN ATTRIBUTE %d>", name);
398}
399
400const char *Nl80211AttributeGeneric::name_string() const {
401 return name_string_.c_str();
402}
403
404} // namespace shill