blob: bb65fccbffac4c2cb52fb63c4e0dd6e5cb9e969b [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) {
Wade Guthrie25cdb382012-12-04 14:04:05 -080041 case NL80211_ATTR_COOKIE:
42 attr.reset(new Nl80211AttributeCookie());
43 break;
44 case NL80211_ATTR_CQM:
45 attr.reset(new Nl80211AttributeCqm());
46 break;
47 case NL80211_ATTR_DISCONNECTED_BY_AP:
48 attr.reset(new Nl80211AttributeDisconnectedByAp());
49 break;
Wade Guthrie16196242012-11-20 15:53:52 -080050 case NL80211_ATTR_DURATION:
51 attr.reset(new Nl80211AttributeDuration());
52 break;
Wade Guthrie25cdb382012-12-04 14:04:05 -080053 case NL80211_ATTR_FRAME:
54 attr.reset(new Nl80211AttributeFrame());
55 break;
56 case NL80211_ATTR_GENERATION:
57 attr.reset(new Nl80211AttributeGeneration());
58 break;
59 case NL80211_ATTR_IFINDEX:
60 attr.reset(new Nl80211AttributeIfindex());
61 break;
62 case NL80211_ATTR_KEY_IDX:
63 attr.reset(new Nl80211AttributeKeyIdx());
64 break;
65 case NL80211_ATTR_KEY_SEQ:
66 attr.reset(new Nl80211AttributeKeySeq());
67 break;
68 case NL80211_ATTR_KEY_TYPE:
69 attr.reset(new Nl80211AttributeKeyType());
70 break;
71 case NL80211_ATTR_MAC:
72 attr.reset(new Nl80211AttributeMac());
73 break;
74 case NL80211_ATTR_REASON_CODE:
75 attr.reset(new Nl80211AttributeReasonCode());
76 break;
77 case NL80211_ATTR_REG_ALPHA2:
78 attr.reset(new Nl80211AttributeRegAlpha2());
79 break;
80 case NL80211_ATTR_REG_INITIATOR:
81 attr.reset(new Nl80211AttributeRegInitiator());
82 break;
83 case NL80211_ATTR_REG_TYPE:
84 attr.reset(new Nl80211AttributeRegType());
85 break;
86 case NL80211_ATTR_RESP_IE:
87 attr.reset(new Nl80211AttributeRespIe());
88 break;
89 case NL80211_ATTR_SCAN_FREQUENCIES:
90 attr.reset(new Nl80211AttributeScanFrequencies());
91 break;
92 case NL80211_ATTR_SCAN_SSIDS:
93 attr.reset(new Nl80211AttributeScanSsids());
94 break;
95 case NL80211_ATTR_STA_INFO:
96 attr.reset(new Nl80211AttributeStaInfo());
97 break;
98 case NL80211_ATTR_STATUS_CODE:
99 attr.reset(new Nl80211AttributeStatusCode());
100 break;
101 case NL80211_ATTR_SUPPORT_MESH_AUTH:
102 attr.reset(new Nl80211AttributeSupportMeshAuth());
103 break;
104 case NL80211_ATTR_TIMED_OUT:
105 attr.reset(new Nl80211AttributeTimedOut());
106 break;
107 case NL80211_ATTR_WIPHY_FREQ:
108 attr.reset(new Nl80211AttributeWiphyFreq());
109 break;
110 case NL80211_ATTR_WIPHY:
111 attr.reset(new Nl80211AttributeWiphy());
112 break;
113 case NL80211_ATTR_WIPHY_NAME:
114 attr.reset(new Nl80211AttributeWiphyName());
115 break;
Wade Guthrie16196242012-11-20 15:53:52 -0800116 default:
117 attr.reset(new Nl80211AttributeGeneric(name));
118 break;
119 }
120 attr->InitFromNlAttr(data);
121 return attr.release();
122}
123
124// Duplicate attribute data, store in map indexed on |name|.
125bool Nl80211Attribute::InitFromNlAttr(const nlattr *other) {
126 if (!other) {
127 LOG(ERROR) << "NULL data";
128 return false;
129 }
130
131 data_ = ByteString(reinterpret_cast<const unsigned char *>(other),
132 nla_total_size(nla_len(const_cast<nlattr *>(other))));
133 return true;
134}
135
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800136// Copies raw attribute data but not the header.
Wade Guthrie16196242012-11-20 15:53:52 -0800137bool Nl80211Attribute::GetRawData(ByteString *output) const {
138 if (!output) {
139 LOG(ERROR) << "Null |output| parameter";
140 return false;
141 }
142
143 *output = data_;
144 return true;
145}
146
147string Nl80211Attribute::RawToString() const {
148 string output = " === RAW: ";
149
150 nlattr *data_nlattr = const_cast<nlattr *>(data());
151 uint16_t length = nla_len(data_nlattr);
152 StringAppendF(&output, "len=%u", length);
153
154 const uint8_t *const_data = reinterpret_cast<const uint8_t *>(data());
155
156 output.append(" DATA: ");
157 for (int i =0 ; i < length; ++i) {
158 StringAppendF(&output, "[%d]=%02x ", i, *(const_data)+i);
159 }
160 output.append(" ==== ");
161 return output;
162}
163
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800164// Nl80211U8Attribute
165
166const char Nl80211U8Attribute::kMyTypeString[] = "uint8_t";
167const Nl80211Attribute::Type Nl80211U8Attribute::kType =
168 Nl80211Attribute::kTypeU8;
169
170bool Nl80211U8Attribute::InitFromNlAttr(const nlattr *input) {
171 if (!input) {
172 LOG(ERROR) << "Null |input| parameter";
173 return false;
174 }
175
176 uint8_t data = NlaGetU8(input);
177 SetU8Value(data);
178 return Nl80211Attribute::InitFromNlAttr(input);
179}
180
181bool Nl80211U8Attribute::GetU8Value(uint8_t *output) const {
182 if (!output) {
183 LOG(ERROR) << "Null |output| parameter";
184 return false;
185 }
186 *output = value_;
187 return true;
188}
189
190bool Nl80211U8Attribute::SetU8Value(uint8_t new_value) {
191 value_ = new_value;
192 return true;
193}
194
195bool Nl80211U8Attribute::AsString(string *output) const {
196 if (!output) {
197 LOG(ERROR) << "Null |output| parameter";
198 return false;
199 }
200 uint8_t value;
201 if (!GetU8Value(&value))
202 return false;
203 *output = StringPrintf("%u", value);
204 return true;
205}
206
207
208// Nl80211U16Attribute
209
210const char Nl80211U16Attribute::kMyTypeString[] = "uint16_t";
211const Nl80211Attribute::Type Nl80211U16Attribute::kType =
212 Nl80211Attribute::kTypeU16;
213
214bool Nl80211U16Attribute::InitFromNlAttr(const nlattr *input) {
215 if (!input) {
216 LOG(ERROR) << "Null |input| parameter";
217 return false;
218 }
219
220 uint16_t data = NlaGetU16(input);
221 SetU16Value(data);
222 return Nl80211Attribute::InitFromNlAttr(input);
223}
224
225bool Nl80211U16Attribute::GetU16Value(uint16_t *output) const {
226 if (!output) {
227 LOG(ERROR) << "Null |output| parameter";
228 return false;
229 }
230 *output = value_;
231 return true;
232}
233
234bool Nl80211U16Attribute::SetU16Value(uint16_t new_value) {
235 value_ = new_value;
236 return true;
237}
238
239bool Nl80211U16Attribute::AsString(string *output) const {
240 if (!output) {
241 LOG(ERROR) << "Null |output| parameter";
242 return false;
243 }
244 uint16_t value;
245 if (!GetU16Value(&value))
246 return false;
247 *output = StringPrintf("%u", value);
248 return true;
249}
250
Wade Guthrie16196242012-11-20 15:53:52 -0800251// Nl80211U32Attribute::
252
253const char Nl80211U32Attribute::kMyTypeString[] = "uint32_t";
254const Nl80211Attribute::Type Nl80211U32Attribute::kType =
255 Nl80211Attribute::kTypeU32;
256
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800257bool Nl80211U32Attribute::InitFromNlAttr(const nlattr *input) {
258 if (!input) {
259 LOG(ERROR) << "Null |input| parameter";
Wade Guthrie16196242012-11-20 15:53:52 -0800260 return false;
261 }
262
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800263 uint32_t data = NlaGetU32(input);
Wade Guthrie16196242012-11-20 15:53:52 -0800264 SetU32Value(data);
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800265 return Nl80211Attribute::InitFromNlAttr(input);
Wade Guthrie16196242012-11-20 15:53:52 -0800266}
267
268bool Nl80211U32Attribute::GetU32Value(uint32_t *output) const {
269 if (!output) {
270 LOG(ERROR) << "Null |output| parameter";
271 return false;
272 }
273 *output = value_;
274 return true;
275}
276
277bool Nl80211U32Attribute::SetU32Value(uint32_t new_value) {
278 value_ = new_value;
279 return true;
280}
281
282bool Nl80211U32Attribute::AsString(string *output) const {
283 if (!output) {
284 LOG(ERROR) << "Null |output| parameter";
285 return false;
286 }
287 uint32_t value;
288 if (!GetU32Value(&value))
289 return false;
290 *output = StringPrintf("%" PRIu32, value);
291 return true;
292}
293
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800294// Nl80211U64Attribute
295
296const char Nl80211U64Attribute::kMyTypeString[] = "uint64_t";
297const Nl80211Attribute::Type Nl80211U64Attribute::kType =
298 Nl80211Attribute::kTypeU64;
299
300bool Nl80211U64Attribute::InitFromNlAttr(const nlattr *input) {
301 if (!input) {
302 LOG(ERROR) << "Null |input| parameter";
303 return false;
304 }
305
306 uint64_t data = NlaGetU64(input);
307 SetU64Value(data);
308 return Nl80211Attribute::InitFromNlAttr(input);
309}
310
311bool Nl80211U64Attribute::GetU64Value(uint64_t *output) const {
312 if (!output) {
313 LOG(ERROR) << "Null |output| parameter";
314 return false;
315 }
316 *output = value_;
317 return true;
318}
319
320bool Nl80211U64Attribute::SetU64Value(uint64_t new_value) {
321 value_ = new_value;
322 return true;
323}
324
325bool Nl80211U64Attribute::AsString(string *output) const {
326 if (!output) {
327 LOG(ERROR) << "Null |output| parameter";
328 return false;
329 }
330 uint64_t value;
331 if (!GetU64Value(&value))
332 return false;
333 *output = StringPrintf("%" PRIu64, value);
334 return true;
335}
336
337// Nl80211FlagAttribute
338
339const char Nl80211FlagAttribute::kMyTypeString[] = "flag";
340const Nl80211Attribute::Type Nl80211FlagAttribute::kType =
341 Nl80211Attribute::kTypeFlag;
342
343bool Nl80211FlagAttribute::InitFromNlAttr(const nlattr *input) {
344 if (!input) {
345 LOG(ERROR) << "Null |input| parameter";
346 return false;
347 }
348
349 // The existence of the parameter means it's true
350 SetFlagValue(true);
351 return Nl80211Attribute::InitFromNlAttr(input);
352}
353
354
355bool Nl80211FlagAttribute::GetFlagValue(bool *output) const {
356 if (!output) {
357 LOG(ERROR) << "Null |output| parameter";
358 return false;
359 }
360 *output = value_;
361 return true;
362}
363
364bool Nl80211FlagAttribute::SetFlagValue(bool new_value) {
365 value_ = new_value;
366 return true;
367}
368
369bool Nl80211FlagAttribute::AsString(string *output) const {
370 if (!output) {
371 LOG(ERROR) << "Null |output| parameter";
372 return false;
373 }
374 bool value;
375 if (!GetFlagValue(&value))
376 return false;
377 *output = StringPrintf("%s", value ? "true" : "false");
378 return true;
379}
380
381// Nl80211StringAttribute
382
383const char Nl80211StringAttribute::kMyTypeString[] = "string";
384const Nl80211Attribute::Type Nl80211StringAttribute::kType =
385 Nl80211Attribute::kTypeString;
386
387bool Nl80211StringAttribute::InitFromNlAttr(const nlattr *input) {
388 if (!input) {
389 LOG(ERROR) << "Null |input| parameter";
390 return false;
391 }
392
393 SetStringValue(NlaGetString(input));
394 return Nl80211Attribute::InitFromNlAttr(input);
395}
396
397bool Nl80211StringAttribute::GetStringValue(string *output) const {
398 if (!output) {
399 LOG(ERROR) << "Null |output| parameter";
400 return false;
401 }
402 *output = value_;
403 return true;
404}
405
406bool Nl80211StringAttribute::SetStringValue(const string new_value) {
407 value_ = new_value;
408 return true;
409}
410
411bool Nl80211StringAttribute::AsString(string *output) const {
412 if (!output) {
413 LOG(ERROR) << "Null |output| parameter";
414 return false;
415 }
416 return GetStringValue(output);
417}
418
419
Wade Guthrie16196242012-11-20 15:53:52 -0800420// Nl80211RawAttribute
421
422const char Nl80211RawAttribute::kMyTypeString[] = "<raw>";
423const Nl80211Attribute::Type Nl80211RawAttribute::kType =
424 Nl80211Attribute::kTypeRaw;
425
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800426bool Nl80211RawAttribute::InitFromNlAttr(const nlattr *input) {
427 if (!input) {
428 LOG(ERROR) << "Null |input| parameter";
Wade Guthrie16196242012-11-20 15:53:52 -0800429 return false;
430 }
431
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800432 return Nl80211Attribute::InitFromNlAttr(input);
Wade Guthrie16196242012-11-20 15:53:52 -0800433}
434
Wade Guthrie25cdb382012-12-04 14:04:05 -0800435bool Nl80211RawAttribute::GetRawValue(ByteString *output) const {
Wade Guthrie16196242012-11-20 15:53:52 -0800436 if (!output) {
437 LOG(ERROR) << "NULL |output|";
438 return false;
439 }
Wade Guthrie25cdb382012-12-04 14:04:05 -0800440 *output = data_;
Wade Guthrie16196242012-11-20 15:53:52 -0800441 return true;
442}
443
444bool Nl80211RawAttribute::AsString(string *output) const {
445 if (!output) {
446 LOG(ERROR) << "Null |output| parameter";
447 return false;
448 }
Wade Guthrie8343f7f2012-12-04 13:52:32 -0800449 // TODO(wdg): Make sure that 'data' is valid.
Wade Guthrie16196242012-11-20 15:53:52 -0800450 const uint8_t *raw_data = reinterpret_cast<const uint8_t *>(data());
451 int total_bytes = nla_len(data());
452 *output = StringPrintf("%d bytes:", total_bytes);
453 for (int i = 0; i < total_bytes; ++i) {
454 StringAppendF(output, " 0x%02x", raw_data[i]);
455 }
456 return true;
457}
458
459// Specific Attributes.
460
Wade Guthrie25cdb382012-12-04 14:04:05 -0800461
462const nl80211_attrs Nl80211AttributeCookie::kName = NL80211_ATTR_COOKIE;
463const char Nl80211AttributeCookie::kNameString[] = "NL80211_ATTR_COOKIE";
464
465const nl80211_attrs Nl80211AttributeCqm::kName = NL80211_ATTR_CQM;
466const char Nl80211AttributeCqm::kNameString[] = "NL80211_ATTR_CQM";
467
468const nl80211_attrs Nl80211AttributeDisconnectedByAp::kName
469 = NL80211_ATTR_DISCONNECTED_BY_AP;
470const char Nl80211AttributeDisconnectedByAp::kNameString[]
471 = "NL80211_ATTR_DISCONNECTED_BY_AP";
472
Wade Guthrie16196242012-11-20 15:53:52 -0800473const nl80211_attrs Nl80211AttributeDuration::kName = NL80211_ATTR_DURATION;
474const char Nl80211AttributeDuration::kNameString[] = "NL80211_ATTR_DURATION";
475
Wade Guthrie25cdb382012-12-04 14:04:05 -0800476const nl80211_attrs Nl80211AttributeFrame::kName = NL80211_ATTR_FRAME;
477const char Nl80211AttributeFrame::kNameString[] = "NL80211_ATTR_FRAME";
478
479const nl80211_attrs Nl80211AttributeGeneration::kName = NL80211_ATTR_GENERATION;
480const char Nl80211AttributeGeneration::kNameString[]
481 = "NL80211_ATTR_GENERATION";
482
483const nl80211_attrs Nl80211AttributeIfindex::kName = NL80211_ATTR_IFINDEX;
484const char Nl80211AttributeIfindex::kNameString[] = "NL80211_ATTR_IFINDEX";
485
486const nl80211_attrs Nl80211AttributeKeyIdx::kName = NL80211_ATTR_KEY_IDX;
487const char Nl80211AttributeKeyIdx::kNameString[] = "NL80211_ATTR_KEY_IDX";
488
489const nl80211_attrs Nl80211AttributeKeySeq::kName = NL80211_ATTR_KEY_SEQ;
490const char Nl80211AttributeKeySeq::kNameString[] = "NL80211_ATTR_KEY_SEQ";
491
492const nl80211_attrs Nl80211AttributeKeyType::kName = NL80211_ATTR_KEY_TYPE;
493const char Nl80211AttributeKeyType::kNameString[] = "NL80211_ATTR_KEY_TYPE";
494
495const nl80211_attrs Nl80211AttributeMac::kName = NL80211_ATTR_MAC;
496const char Nl80211AttributeMac::kNameString[] = "NL80211_ATTR_MAC";
497
498const nl80211_attrs Nl80211AttributeReasonCode::kName
499 = NL80211_ATTR_REASON_CODE;
500const char Nl80211AttributeReasonCode::kNameString[]
501 = "NL80211_ATTR_REASON_CODE";
502
503const nl80211_attrs Nl80211AttributeRegAlpha2::kName = NL80211_ATTR_REG_ALPHA2;
504const char Nl80211AttributeRegAlpha2::kNameString[] = "NL80211_ATTR_REG_ALPHA2";
505
506const nl80211_attrs Nl80211AttributeRegInitiator::kName
507 = NL80211_ATTR_REG_INITIATOR;
508const char Nl80211AttributeRegInitiator::kNameString[]
509 = "NL80211_ATTR_REG_INITIATOR";
510
511const nl80211_attrs Nl80211AttributeRegType::kName = NL80211_ATTR_REG_TYPE;
512const char Nl80211AttributeRegType::kNameString[] = "NL80211_ATTR_REG_TYPE";
513
514const nl80211_attrs Nl80211AttributeRespIe::kName = NL80211_ATTR_RESP_IE;
515const char Nl80211AttributeRespIe::kNameString[] = "NL80211_ATTR_RESP_IE";
516
517const nl80211_attrs Nl80211AttributeScanFrequencies::kName
518 = NL80211_ATTR_SCAN_FREQUENCIES;
519const char Nl80211AttributeScanFrequencies::kNameString[]
520 = "NL80211_ATTR_SCAN_FREQUENCIES";
521
522const nl80211_attrs Nl80211AttributeScanSsids::kName = NL80211_ATTR_SCAN_SSIDS;
523const char Nl80211AttributeScanSsids::kNameString[] = "NL80211_ATTR_SCAN_SSIDS";
524
525const nl80211_attrs Nl80211AttributeStaInfo::kName = NL80211_ATTR_STA_INFO;
526const char Nl80211AttributeStaInfo::kNameString[] = "NL80211_ATTR_STA_INFO";
527
528const nl80211_attrs Nl80211AttributeStatusCode::kName
529 = NL80211_ATTR_STATUS_CODE;
530const char Nl80211AttributeStatusCode::kNameString[]
531 = "NL80211_ATTR_STATUS_CODE";
532
533const nl80211_attrs Nl80211AttributeSupportMeshAuth::kName
534 = NL80211_ATTR_SUPPORT_MESH_AUTH;
535const char Nl80211AttributeSupportMeshAuth::kNameString[]
536 = "NL80211_ATTR_SUPPORT_MESH_AUTH";
537
538const nl80211_attrs Nl80211AttributeTimedOut::kName = NL80211_ATTR_TIMED_OUT;
539const char Nl80211AttributeTimedOut::kNameString[] = "NL80211_ATTR_TIMED_OUT";
540
541const nl80211_attrs Nl80211AttributeWiphyFreq::kName = NL80211_ATTR_WIPHY_FREQ;
542const char Nl80211AttributeWiphyFreq::kNameString[] = "NL80211_ATTR_WIPHY_FREQ";
543
544const nl80211_attrs Nl80211AttributeWiphy::kName = NL80211_ATTR_WIPHY;
545const char Nl80211AttributeWiphy::kNameString[] = "NL80211_ATTR_WIPHY";
546
547const nl80211_attrs Nl80211AttributeWiphyName::kName = NL80211_ATTR_WIPHY_NAME;
548const char Nl80211AttributeWiphyName::kNameString[] = "NL80211_ATTR_WIPHY_NAME";
549
Wade Guthrie16196242012-11-20 15:53:52 -0800550Nl80211AttributeGeneric::Nl80211AttributeGeneric(nl80211_attrs name)
551 : Nl80211RawAttribute(name, "unused-string") {
552 StringAppendF(&name_string_, "<UNKNOWN ATTRIBUTE %d>", name);
553}
554
555const char *Nl80211AttributeGeneric::name_string() const {
556 return name_string_.c_str();
557}
558
559} // namespace shill