blob: d54b5244ac1007c6975099289162be7a890095d5 [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
67// Retrieves a pointer to the raw attribute data but not the header.
68bool 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
95// Nl80211U32Attribute::
96
97const char Nl80211U32Attribute::kMyTypeString[] = "uint32_t";
98const Nl80211Attribute::Type Nl80211U32Attribute::kType =
99 Nl80211Attribute::kTypeU32;
100
101bool Nl80211U32Attribute::InitFromNlAttr(const nlattr *param) {
102 if (!param) {
103 LOG(ERROR) << "Null |param| parameter";
104 return false;
105 }
106
107 uint32_t data = nla_get_u32(const_cast<nlattr *>(param));
108 SetU32Value(data);
109 return Nl80211Attribute::InitFromNlAttr(param);
110}
111
112bool Nl80211U32Attribute::GetU32Value(uint32_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 Nl80211U32Attribute::SetU32Value(uint32_t new_value) {
122 value_ = new_value;
123 return true;
124}
125
126bool Nl80211U32Attribute::AsString(string *output) const {
127 if (!output) {
128 LOG(ERROR) << "Null |output| parameter";
129 return false;
130 }
131 uint32_t value;
132 if (!GetU32Value(&value))
133 return false;
134 *output = StringPrintf("%" PRIu32, value);
135 return true;
136}
137
138// Nl80211RawAttribute
139
140const char Nl80211RawAttribute::kMyTypeString[] = "<raw>";
141const Nl80211Attribute::Type Nl80211RawAttribute::kType =
142 Nl80211Attribute::kTypeRaw;
143
144bool Nl80211RawAttribute::InitFromNlAttr(const nlattr *param) {
145 if (!param) {
146 LOG(ERROR) << "Null |param| parameter";
147 return false;
148 }
149
150 return Nl80211Attribute::InitFromNlAttr(param);
151}
152
153bool Nl80211RawAttribute::GetRawValue(const ByteString **output) const {
154 if (!output) {
155 LOG(ERROR) << "NULL |output|";
156 return false;
157 }
158 *output = &data_;
159 return true;
160}
161
162bool Nl80211RawAttribute::AsString(string *output) const {
163 if (!output) {
164 LOG(ERROR) << "Null |output| parameter";
165 return false;
166 }
167 const uint8_t *raw_data = reinterpret_cast<const uint8_t *>(data());
168 int total_bytes = nla_len(data());
169 *output = StringPrintf("%d bytes:", total_bytes);
170 for (int i = 0; i < total_bytes; ++i) {
171 StringAppendF(output, " 0x%02x", raw_data[i]);
172 }
173 return true;
174}
175
176// Specific Attributes.
177
178const nl80211_attrs Nl80211AttributeDuration::kName = NL80211_ATTR_DURATION;
179const char Nl80211AttributeDuration::kNameString[] = "NL80211_ATTR_DURATION";
180
181Nl80211AttributeGeneric::Nl80211AttributeGeneric(nl80211_attrs name)
182 : Nl80211RawAttribute(name, "unused-string") {
183 StringAppendF(&name_string_, "<UNKNOWN ATTRIBUTE %d>", name);
184}
185
186const char *Nl80211AttributeGeneric::name_string() const {
187 return name_string_.c_str();
188}
189
190} // namespace shill