shill: Breaks nl80211_attribute.* into files appropriate to classes.
This CL *ONLY* breaks nl80211_attribute.* into netlink_attribute.*
and nl80211_attribute.* and adds control_netlink_attribute.*. None of
the netlink or nl80211 code should be changed, here.
BUG=None.
TEST=unittests.
Change-Id: Ia181642af052dceb280a23b5fac25a2400d93e1a
Reviewed-on: https://gerrit.chromium.org/gerrit/44255
Commit-Queue: Wade Guthrie <wdg@chromium.org>
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
diff --git a/Makefile b/Makefile
index 64b549a..700f5c3 100644
--- a/Makefile
+++ b/Makefile
@@ -193,6 +193,7 @@
cellular_service.o \
config80211.o \
connection.o \
+ control_netlink_attribute.o \
crypto_des_cbc.o \
crypto_provider.o \
crypto_rot47.o \
@@ -262,6 +263,7 @@
modem_proxy.o \
modem_simple_proxy.o \
netlink_socket.o \
+ netlink_attribute.o \
nl80211_attribute.o \
nl80211_message.o \
nl80211_socket.o \
diff --git a/attribute_list.cc b/attribute_list.cc
index 757f150..a0d441f 100644
--- a/attribute_list.cc
+++ b/attribute_list.cc
@@ -17,7 +17,7 @@
#include <base/stringprintf.h>
#include "shill/logging.h"
-#include "shill/nl80211_attribute.h"
+#include "shill/netlink_attribute.h"
#include "shill/scope_logger.h"
using base::StringAppendF;
diff --git a/control_netlink_attribute.cc b/control_netlink_attribute.cc
new file mode 100644
index 0000000..2003880
--- /dev/null
+++ b/control_netlink_attribute.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/control_netlink_attribute.h"
+
+#include <netlink/attr.h>
+
+#include "shill/logging.h"
+#include "shill/scope_logger.h"
+
+namespace shill {
+
+const int ControlAttributeFamilyId::kName = CTRL_ATTR_FAMILY_ID;
+const char ControlAttributeFamilyId::kNameString[] = "CTRL_ATTR_FAMILY_ID";
+
+const int ControlAttributeFamilyName::kName = CTRL_ATTR_FAMILY_NAME;
+const char ControlAttributeFamilyName::kNameString[] = "CTRL_ATTR_FAMILY_NAME";
+
+const int ControlAttributeVersion::kName = CTRL_ATTR_VERSION;
+const char ControlAttributeVersion::kNameString[] = "CTRL_ATTR_VERSION";
+
+const int ControlAttributeHdrSize::kName = CTRL_ATTR_HDRSIZE;
+const char ControlAttributeHdrSize::kNameString[] = "CTRL_ATTR_HDRSIZE";
+
+const int ControlAttributeMaxAttr::kName = CTRL_ATTR_MAXATTR;
+const char ControlAttributeMaxAttr::kNameString[] = "CTRL_ATTR_MAXATTR";
+
+const int ControlAttributeAttrOps::kName = CTRL_ATTR_OPS;
+const char ControlAttributeAttrOps::kNameString[] = "CTRL_ATTR_OPS";
+
+ControlAttributeAttrOps::ControlAttributeAttrOps()
+ : NetlinkNestedAttribute(kName, kNameString) {}
+
+bool ControlAttributeAttrOps::InitFromNlAttr(const nlattr *const_data) {
+ static const NestedData kOps[CTRL_ATTR_OP_MAX + 1] = {
+ {{NLA_U32, 0, 0}, "CTRL_ATTR_OP_UNSPEC", NULL, 0, false},
+ {{NLA_U32, 0, 0}, "CTRL_ATTR_OP_ID", NULL, 0, false},
+ {{NLA_U32, 0, 0}, "CTRL_ATTR_OP_FLAGS", NULL, 0, false},
+ };
+ static const NestedData kOpsList[] = {
+ {{NLA_NESTED, 0, 0 }, "FIRST", &kOps[0], arraysize(kOps), true},
+ };
+
+ if (!InitNestedFromNlAttr(value_.get(),
+ kOpsList,
+ arraysize(kOpsList),
+ const_data)) {
+ LOG(ERROR) << "InitNestedFromNlAttr() failed";
+ return false;
+ }
+ has_a_value_ = true;
+ return true;
+}
+
+const int ControlAttributeMcastGroups::kName = CTRL_ATTR_MCAST_GROUPS;
+const char ControlAttributeMcastGroups::kNameString[] =
+ "CTRL_ATTR_MCAST_GROUPS";
+
+ControlAttributeMcastGroups::ControlAttributeMcastGroups()
+ : NetlinkNestedAttribute(kName, kNameString) {}
+
+bool ControlAttributeMcastGroups::InitFromNlAttr(const nlattr *const_data) {
+ static const NestedData kMulticast[CTRL_ATTR_MCAST_GRP_MAX + 1] = {
+ {{NLA_U32, 0, 0}, "CTRL_ATTR_MCAST_GRP_UNSPEC", NULL, 0, false},
+ {{NLA_STRING, 0, 0}, "CTRL_ATTR_MCAST_GRP_NAME", NULL, 0, false},
+ {{NLA_U32, 0, 0}, "CTRL_ATTR_MCAST_GRP_ID", NULL, 0, false},
+ };
+ static const NestedData kMulticastList[] = {
+ {{NLA_NESTED, 0, 0}, "FIRST", &kMulticast[0], arraysize(kMulticast),
+ true},
+ };
+
+ if (!InitNestedFromNlAttr(value_.get(),
+ kMulticastList,
+ arraysize(kMulticastList),
+ const_data)) {
+ LOG(ERROR) << "InitNestedFromNlAttr() failed";
+ return false;
+ }
+ has_a_value_ = true;
+ return true;
+}
+
+} // namespace shill
diff --git a/control_netlink_attribute.h b/control_netlink_attribute.h
new file mode 100644
index 0000000..83cd7ee
--- /dev/null
+++ b/control_netlink_attribute.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_CONTROL_NETLINK_ATTRIBUTE_H_
+#define SHILL_CONTROL_NETLINK_ATTRIBUTE_H_
+
+#include <netlink/attr.h>
+
+#include "shill/netlink_attribute.h"
+
+struct nlattr;
+
+namespace shill {
+
+// Control.
+
+class ControlAttributeFamilyId : public NetlinkU16Attribute {
+ public:
+ static const int kName;
+ static const char kNameString[];
+ ControlAttributeFamilyId() : NetlinkU16Attribute(kName, kNameString) {}
+};
+
+class ControlAttributeFamilyName : public NetlinkStringAttribute {
+ public:
+ static const int kName;
+ static const char kNameString[];
+ ControlAttributeFamilyName() : NetlinkStringAttribute(kName, kNameString) {}
+};
+
+class ControlAttributeVersion : public NetlinkU32Attribute {
+ public:
+ static const int kName;
+ static const char kNameString[];
+ ControlAttributeVersion() : NetlinkU32Attribute(kName, kNameString) {}
+};
+
+class ControlAttributeHdrSize : public NetlinkU32Attribute {
+ public:
+ static const int kName;
+ static const char kNameString[];
+ ControlAttributeHdrSize() : NetlinkU32Attribute(kName, kNameString) {}
+};
+
+class ControlAttributeMaxAttr : public NetlinkU32Attribute {
+ public:
+ static const int kName;
+ static const char kNameString[];
+ ControlAttributeMaxAttr() : NetlinkU32Attribute(kName, kNameString) {}
+};
+
+class ControlAttributeAttrOps : public NetlinkNestedAttribute {
+ public:
+ static const int kName;
+ static const char kNameString[];
+ ControlAttributeAttrOps();
+ virtual bool InitFromNlAttr(const nlattr *data);
+};
+
+class ControlAttributeMcastGroups : public NetlinkNestedAttribute {
+ public:
+ static const int kName;
+ static const char kNameString[];
+ ControlAttributeMcastGroups();
+ virtual bool InitFromNlAttr(const nlattr *data);
+};
+
+} // namespace shill
+
+#endif // SHILL_CONTROL_NETLINK_ATTRIBUTE_H_
diff --git a/netlink_attribute.cc b/netlink_attribute.cc
new file mode 100644
index 0000000..4235c5d
--- /dev/null
+++ b/netlink_attribute.cc
@@ -0,0 +1,978 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/netlink_attribute.h"
+
+#include <netlink/attr.h>
+
+#include <string>
+
+#include <base/format_macros.h>
+#include <base/stringprintf.h>
+
+#include "shill/attribute_list.h"
+#include "shill/control_netlink_attribute.h"
+#include "shill/logging.h"
+#include "shill/nl80211_attribute.h"
+#include "shill/scope_logger.h"
+
+using std::string;
+
+using base::StringAppendF;
+using base::StringPrintf;
+
+namespace shill {
+
+// This is a type-corrected copy of |nla_for_each_nested| from libnl.
+#define nla_for_each_nested_type_corrected(pos, nla, rem) \
+ for (pos = reinterpret_cast<struct nlattr *>(nla_data(nla)), \
+ rem = nla_len(nla); \
+ nla_ok(pos, rem); \
+ pos = nla_next(pos, &(rem)))
+
+NetlinkAttribute::NetlinkAttribute(int id,
+ const char *id_string,
+ Type datatype,
+ const char *datatype_string)
+ : has_a_value_(false), id_(id), id_string_(id_string), datatype_(datatype),
+ datatype_string_(datatype_string) {}
+
+// static
+NetlinkAttribute *NetlinkAttribute::NewNl80211AttributeFromId(int id) {
+ scoped_ptr<NetlinkAttribute> attr;
+ switch (id) {
+ case NL80211_ATTR_COOKIE:
+ attr.reset(new Nl80211AttributeCookie());
+ break;
+ case NL80211_ATTR_CQM:
+ attr.reset(new Nl80211AttributeCqm());
+ break;
+ case NL80211_ATTR_DISCONNECTED_BY_AP:
+ attr.reset(new Nl80211AttributeDisconnectedByAp());
+ break;
+ case NL80211_ATTR_DURATION:
+ attr.reset(new Nl80211AttributeDuration());
+ break;
+ case NL80211_ATTR_FRAME:
+ attr.reset(new Nl80211AttributeFrame());
+ break;
+ case NL80211_ATTR_GENERATION:
+ attr.reset(new Nl80211AttributeGeneration());
+ break;
+ case NL80211_ATTR_IFINDEX:
+ attr.reset(new Nl80211AttributeIfindex());
+ break;
+ case NL80211_ATTR_KEY_IDX:
+ attr.reset(new Nl80211AttributeKeyIdx());
+ break;
+ case NL80211_ATTR_KEY_SEQ:
+ attr.reset(new Nl80211AttributeKeySeq());
+ break;
+ case NL80211_ATTR_KEY_TYPE:
+ attr.reset(new Nl80211AttributeKeyType());
+ break;
+ case NL80211_ATTR_MAC:
+ attr.reset(new Nl80211AttributeMac());
+ break;
+ case NL80211_ATTR_REASON_CODE:
+ attr.reset(new Nl80211AttributeReasonCode());
+ break;
+ case NL80211_ATTR_REG_ALPHA2:
+ attr.reset(new Nl80211AttributeRegAlpha2());
+ break;
+ case NL80211_ATTR_REG_INITIATOR:
+ attr.reset(new Nl80211AttributeRegInitiator());
+ break;
+ case NL80211_ATTR_REG_TYPE:
+ attr.reset(new Nl80211AttributeRegType());
+ break;
+ case NL80211_ATTR_RESP_IE:
+ attr.reset(new Nl80211AttributeRespIe());
+ break;
+ case NL80211_ATTR_SCAN_FREQUENCIES:
+ attr.reset(new Nl80211AttributeScanFrequencies());
+ break;
+ case NL80211_ATTR_SCAN_SSIDS:
+ attr.reset(new Nl80211AttributeScanSsids());
+ break;
+ case NL80211_ATTR_STA_INFO:
+ attr.reset(new Nl80211AttributeStaInfo());
+ break;
+ case NL80211_ATTR_STATUS_CODE:
+ attr.reset(new Nl80211AttributeStatusCode());
+ break;
+ case NL80211_ATTR_SUPPORT_MESH_AUTH:
+ attr.reset(new Nl80211AttributeSupportMeshAuth());
+ break;
+ case NL80211_ATTR_TIMED_OUT:
+ attr.reset(new Nl80211AttributeTimedOut());
+ break;
+ case NL80211_ATTR_WIPHY_FREQ:
+ attr.reset(new Nl80211AttributeWiphyFreq());
+ break;
+ case NL80211_ATTR_WIPHY:
+ attr.reset(new Nl80211AttributeWiphy());
+ break;
+ case NL80211_ATTR_WIPHY_NAME:
+ attr.reset(new Nl80211AttributeWiphyName());
+ break;
+ default:
+ attr.reset(new NetlinkAttributeGeneric(id));
+ break;
+ }
+ return attr.release();
+}
+
+// static
+NetlinkAttribute *NetlinkAttribute::NewControlAttributeFromId(int id) {
+ scoped_ptr<NetlinkAttribute> attr;
+ switch (id) {
+ case CTRL_ATTR_FAMILY_ID:
+ attr.reset(new ControlAttributeFamilyId());
+ break;
+ case CTRL_ATTR_FAMILY_NAME:
+ attr.reset(new ControlAttributeFamilyName());
+ break;
+ case CTRL_ATTR_VERSION:
+ attr.reset(new ControlAttributeVersion());
+ break;
+ case CTRL_ATTR_HDRSIZE:
+ attr.reset(new ControlAttributeHdrSize());
+ break;
+ case CTRL_ATTR_MAXATTR:
+ attr.reset(new ControlAttributeMaxAttr());
+ break;
+ case CTRL_ATTR_OPS:
+ attr.reset(new ControlAttributeAttrOps());
+ break;
+ case CTRL_ATTR_MCAST_GROUPS:
+ attr.reset(new ControlAttributeMcastGroups());
+ break;
+ default:
+ attr.reset(new NetlinkAttributeGeneric(id));
+ break;
+ }
+ return attr.release();
+}
+
+// Duplicate attribute data, store in map indexed on |id|.
+bool NetlinkAttribute::InitFromNlAttr(const nlattr *other) {
+ if (!other) {
+ LOG(ERROR) << "NULL data";
+ return false;
+ }
+
+ data_ = ByteString(
+ reinterpret_cast<char *>(nla_data(const_cast<nlattr *>(other))),
+ nla_len(const_cast<nlattr *>(other)));
+ return true;
+}
+
+bool NetlinkAttribute::GetU8Value(uint8_t *value) const {
+ LOG(ERROR) << "Attribute is not of type 'U8'";
+ return false;
+}
+
+bool NetlinkAttribute::SetU8Value(uint8_t value) {
+ LOG(ERROR) << "Attribute is not of type 'U8'";
+ return false;
+}
+
+bool NetlinkAttribute::GetU16Value(uint16_t *value) const {
+ LOG(ERROR) << "Attribute is not of type 'U16'";
+ return false;
+}
+
+bool NetlinkAttribute::SetU16Value(uint16_t value) {
+ LOG(ERROR) << "Attribute is not of type 'U16'";
+ return false;
+}
+
+bool NetlinkAttribute::GetU32Value(uint32_t *value) const {
+ LOG(ERROR) << "Attribute is not of type 'U32'";
+ return false;
+}
+
+bool NetlinkAttribute::SetU32Value(uint32_t value) {
+ LOG(ERROR) << "Attribute is not of type 'U32'";
+ return false;
+}
+
+bool NetlinkAttribute::GetU64Value(uint64_t *value) const {
+ LOG(ERROR) << "Attribute is not of type 'U64'";
+ return false;
+}
+
+bool NetlinkAttribute::SetU64Value(uint64_t value) {
+ LOG(ERROR) << "Attribute is not of type 'U64'";
+ return false;
+}
+
+bool NetlinkAttribute::GetFlagValue(bool *value) const {
+ LOG(ERROR) << "Attribute is not of type 'Flag'";
+ return false;
+}
+
+bool NetlinkAttribute::SetFlagValue(bool value) {
+ LOG(ERROR) << "Attribute is not of type 'Flag'";
+ return false;
+}
+
+bool NetlinkAttribute::GetStringValue(string *value) const {
+ LOG(ERROR) << "Attribute is not of type 'String'";
+ return false;
+}
+
+bool NetlinkAttribute::SetStringValue(string value) {
+ LOG(ERROR) << "Attribute is not of type 'String'";
+ return false;
+}
+
+bool NetlinkAttribute::GetNestedAttributeList(AttributeListRefPtr *value) {
+ LOG(ERROR) << "Attribute is not of type 'Nested'";
+ return false;
+}
+
+bool NetlinkAttribute::ConstGetNestedAttributeList(
+ AttributeListConstRefPtr *value) const {
+ LOG(ERROR) << "Attribute is not of type 'Nested'";
+ return false;
+}
+
+bool NetlinkAttribute::SetNestedHasAValue() {
+ LOG(ERROR) << "Attribute is not of type 'Nested'";
+ return false;
+}
+
+bool NetlinkAttribute::GetRawValue(ByteString *value) const {
+ LOG(ERROR) << "Attribute is not of type 'Raw'";
+ return false;
+}
+
+bool NetlinkAttribute::SetRawValue(const ByteString new_value) {
+ LOG(ERROR) << "Attribute is not of type 'Raw'";
+ return false;
+}
+
+void NetlinkAttribute::Print(int log_level, int indent) const {
+ string attribute_value;
+ SLOG(WiFi, log_level) << HeaderToPrint(indent) << " "
+ << (ToString(&attribute_value) ? attribute_value :
+ "<DOES NOT EXIST>");
+}
+
+string NetlinkAttribute::RawToString() const {
+ string output = " === RAW: ";
+
+ if (!has_a_value_) {
+ StringAppendF(&output, "(empty)");
+ return output;
+ }
+
+ uint16_t length = data_.GetLength();
+ const uint8_t *const_data = data_.GetConstData();
+
+ StringAppendF(&output, "len=%u", length);
+ output.append(" DATA: ");
+ for (int i =0 ; i < length; ++i) {
+ StringAppendF(&output, "[%d]=%02x ", i, *(const_data)+i);
+ }
+ output.append(" ==== ");
+ return output;
+}
+
+string NetlinkAttribute::HeaderToPrint(int indent) const {
+ static const int kSpacesPerIndent = 2;
+ return StringPrintf("%*s%s(%d) %s %s=",
+ indent * kSpacesPerIndent, "",
+ id_string(),
+ id(),
+ datatype_string(),
+ ((has_a_value()) ? "": "UNINITIALIZED "));
+}
+
+ByteString NetlinkAttribute::EncodeGeneric(const unsigned char *data,
+ size_t num_bytes) const {
+ nlattr header;
+ header.nla_type = id();
+ header.nla_len = nla_attr_size(num_bytes);
+ ByteString result(reinterpret_cast<unsigned char *>(&header), sizeof(header));
+ result.Resize(NLA_HDRLEN); // Add padding after the header.
+ if (data && (num_bytes != 0)) {
+ result.Append(ByteString(data, num_bytes));
+ }
+ result.Resize(nla_total_size(num_bytes)); // Add padding.
+ return result;
+}
+
+// NetlinkU8Attribute
+
+const char NetlinkU8Attribute::kMyTypeString[] = "uint8_t";
+const NetlinkAttribute::Type NetlinkU8Attribute::kType =
+ NetlinkAttribute::kTypeU8;
+
+bool NetlinkU8Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ uint8_t data = NlaGetU8(input);
+ SetU8Value(data);
+ return NetlinkAttribute::InitFromNlAttr(input);
+}
+
+bool NetlinkU8Attribute::GetU8Value(uint8_t *output) const {
+ if (!has_a_value_) {
+ SLOG(WiFi, 7) << "U8 attribute " << id_string()
+ << " hasn't been set to any value.";
+ return false;
+ }
+ if (output) {
+ *output = value_;
+ }
+ return true;
+}
+
+bool NetlinkU8Attribute::SetU8Value(uint8_t new_value) {
+ value_ = new_value;
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkU8Attribute::ToString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ uint8_t value;
+ if (!GetU8Value(&value))
+ return false;
+ *output = StringPrintf("%u", value);
+ return true;
+}
+
+ByteString NetlinkU8Attribute::Encode() const {
+ return NetlinkAttribute::EncodeGeneric(
+ reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
+}
+
+
+// NetlinkU16Attribute
+
+const char NetlinkU16Attribute::kMyTypeString[] = "uint16_t";
+const NetlinkAttribute::Type NetlinkU16Attribute::kType =
+ NetlinkAttribute::kTypeU16;
+
+bool NetlinkU16Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ uint16_t data = NlaGetU16(input);
+ SetU16Value(data);
+ return NetlinkAttribute::InitFromNlAttr(input);
+}
+
+bool NetlinkU16Attribute::GetU16Value(uint16_t *output) const {
+ if (!has_a_value_) {
+ SLOG(WiFi, 7) << "U16 attribute " << id_string()
+ << " hasn't been set to any value.";
+ return false;
+ }
+ if (output) {
+ *output = value_;
+ }
+ return true;
+}
+
+bool NetlinkU16Attribute::SetU16Value(uint16_t new_value) {
+ value_ = new_value;
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkU16Attribute::ToString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ uint16_t value;
+ if (!GetU16Value(&value))
+ return false;
+ *output = StringPrintf("%u", value);
+ return true;
+}
+
+ByteString NetlinkU16Attribute::Encode() const {
+ return NetlinkAttribute::EncodeGeneric(
+ reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
+}
+
+// NetlinkU32Attribute::
+
+const char NetlinkU32Attribute::kMyTypeString[] = "uint32_t";
+const NetlinkAttribute::Type NetlinkU32Attribute::kType =
+ NetlinkAttribute::kTypeU32;
+
+bool NetlinkU32Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ uint32_t data = NlaGetU32(input);
+ SetU32Value(data);
+ return NetlinkAttribute::InitFromNlAttr(input);
+}
+
+bool NetlinkU32Attribute::GetU32Value(uint32_t *output) const {
+ if (!has_a_value_) {
+ SLOG(WiFi, 7) << "U32 attribute " << id_string()
+ << " hasn't been set to any value.";
+ return false;
+ }
+ if (output) {
+ *output = value_;
+ }
+ return true;
+}
+
+bool NetlinkU32Attribute::SetU32Value(uint32_t new_value) {
+ value_ = new_value;
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkU32Attribute::ToString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ uint32_t value;
+ if (!GetU32Value(&value))
+ return false;
+ *output = StringPrintf("%" PRIu32, value);
+ return true;
+}
+
+ByteString NetlinkU32Attribute::Encode() const {
+ return NetlinkAttribute::EncodeGeneric(
+ reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
+}
+
+// NetlinkU64Attribute
+
+const char NetlinkU64Attribute::kMyTypeString[] = "uint64_t";
+const NetlinkAttribute::Type NetlinkU64Attribute::kType =
+ NetlinkAttribute::kTypeU64;
+
+bool NetlinkU64Attribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ uint64_t data = NlaGetU64(input);
+ SetU64Value(data);
+ return NetlinkAttribute::InitFromNlAttr(input);
+}
+
+bool NetlinkU64Attribute::GetU64Value(uint64_t *output) const {
+ if (!has_a_value_) {
+ SLOG(WiFi, 7) << "U64 attribute " << id_string()
+ << " hasn't been set to any value.";
+ return false;
+ }
+ if (output) {
+ *output = value_;
+ }
+ return true;
+}
+
+bool NetlinkU64Attribute::SetU64Value(uint64_t new_value) {
+ value_ = new_value;
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkU64Attribute::ToString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ uint64_t value;
+ if (!GetU64Value(&value))
+ return false;
+ *output = StringPrintf("%" PRIu64, value);
+ return true;
+}
+
+ByteString NetlinkU64Attribute::Encode() const {
+ return NetlinkAttribute::EncodeGeneric(
+ reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
+}
+
+// NetlinkFlagAttribute
+
+const char NetlinkFlagAttribute::kMyTypeString[] = "flag";
+const NetlinkAttribute::Type NetlinkFlagAttribute::kType =
+ NetlinkAttribute::kTypeFlag;
+
+bool NetlinkFlagAttribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ // The existence of the parameter means it's true
+ SetFlagValue(true);
+ return NetlinkAttribute::InitFromNlAttr(input);
+}
+
+
+bool NetlinkFlagAttribute::GetFlagValue(bool *output) const {
+ if (output) {
+ // The lack of the existence of the attribute implies 'false'.
+ *output = (has_a_value_) ? value_ : false;
+ }
+ return true;
+}
+
+bool NetlinkFlagAttribute::SetFlagValue(bool new_value) {
+ value_ = new_value;
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkFlagAttribute::ToString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ bool value;
+ if (!GetFlagValue(&value))
+ return false;
+ *output = StringPrintf("%s", value ? "true" : "false");
+ return true;
+}
+
+ByteString NetlinkFlagAttribute::Encode() const {
+ if (has_a_value_ && value_) {
+ return NetlinkAttribute::EncodeGeneric(NULL, 0);
+ }
+ return ByteString(); // Encoding of nothing implies 'false'.
+}
+
+// NetlinkStringAttribute
+
+const char NetlinkStringAttribute::kMyTypeString[] = "string";
+const NetlinkAttribute::Type NetlinkStringAttribute::kType =
+ NetlinkAttribute::kTypeString;
+
+bool NetlinkStringAttribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ SetStringValue(NlaGetString(input));
+ return NetlinkAttribute::InitFromNlAttr(input);
+}
+
+bool NetlinkStringAttribute::GetStringValue(string *output) const {
+ if (!has_a_value_) {
+ SLOG(WiFi, 7) << "String attribute " << id_string()
+ << " hasn't been set to any value.";
+ return false;
+ }
+ if (output) {
+ *output = value_;
+ }
+ return true;
+}
+
+bool NetlinkStringAttribute::SetStringValue(const string new_value) {
+ value_ = new_value;
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkStringAttribute::ToString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ string value;
+ if (!GetStringValue(&value))
+ return false;
+
+ *output = StringPrintf("'%s'", value.c_str());
+ return true;
+}
+
+ByteString NetlinkStringAttribute::Encode() const {
+ return NetlinkAttribute::EncodeGeneric(
+ reinterpret_cast<const unsigned char *>(value_.c_str()),
+ value_.size() + 1);
+}
+
+// NetlinkNestedAttribute
+
+const char NetlinkNestedAttribute::kMyTypeString[] = "nested";
+const NetlinkAttribute::Type NetlinkNestedAttribute::kType =
+ NetlinkAttribute::kTypeNested;
+
+NetlinkNestedAttribute::NetlinkNestedAttribute(int id,
+ const char *id_string) :
+ NetlinkAttribute(id, id_string, kType, kMyTypeString),
+ value_(new AttributeList) {}
+
+ByteString NetlinkNestedAttribute::Encode() const {
+ // Encode attribute header.
+ nlattr header;
+ header.nla_type = id();
+ header.nla_len = nla_attr_size(sizeof(header));
+ ByteString result(reinterpret_cast<unsigned char *>(&header), sizeof(header));
+ result.Resize(NLA_HDRLEN); // Add padding after the header.
+
+ // Encode all nested attributes.
+ std::map<int, AttributeList::AttributePointer>::const_iterator attribute;
+ for (attribute = value_->attributes_.begin();
+ attribute != value_->attributes_.end();
+ ++attribute) {
+ // Each attribute appends appropriate padding so it's not necessary to
+ // re-add padding.
+ result.Append(attribute->second->Encode());
+ }
+
+ // Go back and fill-in the size.
+ nlattr *new_header = reinterpret_cast<nlattr *>(result.GetData());
+ new_header->nla_len = result.GetLength();
+
+ return result;
+}
+
+void NetlinkNestedAttribute::Print(int log_level, int indent) const {
+ SLOG(WiFi, log_level) << HeaderToPrint(indent);
+ value_->Print(log_level, indent + 1);
+}
+
+bool NetlinkNestedAttribute::ToString(std::string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+
+ // This should never be called (attribute->ToString is only called
+ // from attribute->Print but NetlinkNestedAttribute::Print doesn't call
+ // |ToString|. Still, we should print something in case we got here
+ // accidentally.
+ LOG(WARNING) << "It is unexpected for this method to be called.";
+ output->append("<Nested Attribute>");
+ return true;
+}
+
+bool NetlinkNestedAttribute::GetNestedAttributeList(
+ AttributeListRefPtr *output) {
+ // Not checking |has_a_value| since GetNestedAttributeList is called to get
+ // a newly created AttributeList in order to have something to which to add
+ // attributes.
+ if (output) {
+ *output = value_;
+ }
+ return true;
+}
+
+bool NetlinkNestedAttribute::ConstGetNestedAttributeList(
+ AttributeListConstRefPtr *output) const {
+ if (!has_a_value_) {
+ LOG(ERROR) << "Attribute does not exist.";
+ return false;
+ }
+ if (output) {
+ *output = value_;
+ }
+ return true;
+}
+
+bool NetlinkNestedAttribute::SetNestedHasAValue() {
+ has_a_value_ = true;
+ return true;
+}
+
+// static
+bool NetlinkNestedAttribute::InitNestedFromNlAttr(
+ AttributeList *list,
+ const NestedData *nested_template,
+ size_t nested_template_size,
+ const nlattr *const_data) {
+ if (!nested_template) {
+ LOG(ERROR) << "Null |nested_template| parameter";
+ return false;
+ }
+ if ((nested_template_size == 1) && (nested_template[0].is_array)) {
+ return ParseNestedArray(list, *nested_template, const_data);
+ } else {
+ return ParseNestedStructure(list, nested_template, nested_template_size,
+ const_data);
+ }
+ return true;
+}
+
+// A nested array provides an arbitrary number of children, all of the same
+// data type. Each array element may be a simple type or may be a structure.
+//
+// static
+bool NetlinkNestedAttribute::ParseNestedArray(
+ AttributeList *list,
+ const NestedData &array_template,
+ const nlattr *const_data) {
+ if (!list) {
+ LOG(ERROR) << "NULL |list| parameter";
+ return false;
+ }
+ if (!const_data) {
+ LOG(ERROR) << "Null |const_data| parameter";
+ return false;
+ }
+ // Casting away constness since |nla_parse_nested| doesn't mark its input as
+ // const even though it doesn't modify this input parameter.
+ nlattr *attrs = const_cast<nlattr *>(const_data);
+
+ struct nlattr *attr;
+ int remaining;
+ // The |nlattr::nla_type| value for array elements in the provided data may
+ // start on any number and are allowed to be discontiguous. In order to
+ // skirt writing an iterator, this code replaces the |nla_type| with a
+ // contiguous |id|, starting at 1 (note that, while nested structure
+ // attributes may not have an |nlattr::nla_type| valued at zero, no such
+ // restriction exists for nested array attributes -- this code starts the id
+ // at zero in order to be consistent with nested structures).
+ //
+ // TODO(wdg): Determine whether any code depends on the value of
+ // |nlattr::nla_type| for nested array attributes.
+ int id = 1;
+ nla_for_each_nested_type_corrected(attr, attrs, remaining) {
+ string attribute_name = StringPrintf("%s_%d",
+ array_template.attribute_name, id);
+ AddAttributeToNested(list, array_template.policy.type, id, attribute_name,
+ *attr, array_template);
+ ++id;
+ }
+ return true;
+}
+
+// A nested structure provides a fixed set of child attributes (some of
+// which may be optional). The caller provides the expectation of the members
+// and values of a nested structure in the supplied 'policy' template
+// (|struct_template|).
+//
+// static
+bool NetlinkNestedAttribute::ParseNestedStructure(
+ AttributeList *list,
+ const NestedData *struct_template,
+ size_t nested_template_size,
+ const nlattr *const_data) {
+ if (!list) {
+ LOG(ERROR) << "NULL |list| parameter";
+ return false;
+ }
+ if (!struct_template) {
+ LOG(ERROR) << "Null |struct_template| parameter";
+ return false;
+ }
+ if (nested_template_size == 0) {
+ LOG(ERROR) << "|nested_template_size| parameter is zero";
+ return false;
+ }
+ if (!const_data) {
+ LOG(ERROR) << "Null |const_data| parameter";
+ return false;
+ }
+ // Casting away constness since |nla_parse_nested| doesn't mark its input as
+ // const even though it doesn't modify this input parameter.
+ nlattr *attr_data = const_cast<nlattr *>(const_data);
+
+ // |nla_parse_nested| requires an array of |nla_policy|. While an attribute id
+ // of zero is illegal, we still need to fill that spot in the policy
+ // array so the loop will start at zero.
+ scoped_array<nla_policy> policy(new nla_policy[nested_template_size]);
+ for (size_t id = 0; id < nested_template_size ; ++id) {
+ memcpy(&policy[id], &struct_template[id].policy, sizeof(nla_policy));
+ }
+
+ // |nla_parse_nested| builds an array of |nlattr| from the input message.
+ scoped_array<nlattr *>attr(new nlattr *[nested_template_size]);
+ if (nla_parse_nested(attr.get(), nested_template_size-1, attr_data,
+ policy.get())) {
+ LOG(ERROR) << "nla_parse_nested failed";
+ return false;
+ }
+
+ // Note that the attribute id of zero is illegal so we'll start with id=1.
+ for (size_t id = 1; id < nested_template_size; ++id) {
+ // Add |attr[id]| if it exists, otherwise, it's a legally omitted optional
+ // attribute.
+ if (attr[id]) {
+ AddAttributeToNested(list, policy[id].type, id,
+ struct_template[id].attribute_name, *attr[id],
+ struct_template[id]);
+ }
+ }
+ return true;
+}
+
+// static
+void NetlinkNestedAttribute::AddAttributeToNested(
+ AttributeList *list, uint16_t type, size_t id, const string &attribute_name,
+ const nlattr &attr, const NestedData &nested_template) {
+ switch (type) {
+ case NLA_UNSPEC:
+ list->CreateRawAttribute(id, attribute_name.c_str());
+ list->SetRawAttributeValue(id, ByteString(
+ reinterpret_cast<const char *>(nla_data(&attr)), nla_len(&attr)));
+ break;
+ case NLA_U8:
+ list->CreateU8Attribute(id, attribute_name.c_str());
+ list->SetU8AttributeValue(id, NlaGetU8(&attr));
+ break;
+ case NLA_U16:
+ list->CreateU16Attribute(id, attribute_name.c_str());
+ list->SetU16AttributeValue(id, NlaGetU16(&attr));
+ break;
+ case NLA_U32:
+ list->CreateU32Attribute(id, attribute_name.c_str());
+ list->SetU32AttributeValue(id, NlaGetU32(&attr));
+ break;
+ case NLA_U64:
+ list->CreateU64Attribute(id, attribute_name.c_str());
+ list->SetU64AttributeValue(id, NlaGetU64(&attr));
+ break;
+ case NLA_FLAG:
+ list->CreateFlagAttribute(id, attribute_name.c_str());
+ list->SetFlagAttributeValue(id, true);
+ break;
+ case NLA_STRING:
+ // Note that nested structure attributes are validated by |validate_nla|
+ // which requires a string attribute to have at least 1 character
+ // (presumably for the '\0') while the kernel can create an empty string
+ // for at least one nested string array attribute type
+ // (NL80211_ATTR_SCAN_SSIDS -- the emptyness of the string is exhibited
+ // by the value of |nlattr::nla_len|). This code handles both cases.
+ list->CreateStringAttribute(id, attribute_name.c_str());
+ if (nla_len(&attr) <= 0) {
+ list->SetStringAttributeValue(id, "");
+ } else {
+ list->SetStringAttributeValue(id, NlaGetString(&attr));
+ }
+ break;
+ case NLA_NESTED:
+ {
+ if (!nested_template.deeper_nesting) {
+ LOG(ERROR) << "No rules for nesting " << attribute_name
+ << ". Ignoring.";
+ break;
+ }
+ list->CreateNestedAttribute(id, attribute_name.c_str());
+
+ // Now, handle the nested data.
+ AttributeListRefPtr nested_attribute;
+ if (!list->GetNestedAttributeList(id, &nested_attribute) ||
+ !nested_attribute) {
+ LOG(FATAL) << "Couldn't get attribute " << attribute_name
+ << " which we just created.";
+ break;
+ }
+
+ if (!InitNestedFromNlAttr(nested_attribute.get(),
+ nested_template.deeper_nesting,
+ nested_template.deeper_nesting_size,
+ &attr)) {
+ LOG(ERROR) << "Couldn't parse attribute " << attribute_name;
+ break;
+ }
+ list->SetNestedAttributeHasAValue(id);
+ }
+ break;
+ default:
+ LOG(ERROR) << "Discarding " << attribute_name
+ << ". Attribute has unhandled type " << type << ".";
+ break;
+ }
+}
+
+// NetlinkRawAttribute
+
+const char NetlinkRawAttribute::kMyTypeString[] = "<raw>";
+const NetlinkAttribute::Type NetlinkRawAttribute::kType =
+ NetlinkAttribute::kTypeRaw;
+
+bool NetlinkRawAttribute::InitFromNlAttr(const nlattr *input) {
+ if (!input) {
+ LOG(ERROR) << "Null |input| parameter";
+ return false;
+ }
+
+ if (!NetlinkAttribute::InitFromNlAttr(input)) {
+ return false;
+ }
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkRawAttribute::GetRawValue(ByteString *output) const {
+ if (!has_a_value_) {
+ SLOG(WiFi, 7) << "Raw attribute " << id_string()
+ << " hasn't been set to any value.";
+ return false;
+ }
+ if (output) {
+ *output = data_;
+ }
+ return true;
+}
+
+bool NetlinkRawAttribute::SetRawValue(const ByteString new_value) {
+ data_ = new_value;
+ has_a_value_ = true;
+ return true;
+}
+
+bool NetlinkRawAttribute::ToString(string *output) const {
+ if (!output) {
+ LOG(ERROR) << "Null |output| parameter";
+ return false;
+ }
+ if (!has_a_value_) {
+ SLOG(WiFi, 7) << "Raw attribute " << id_string()
+ << " hasn't been set to any value.";
+ return false;
+ }
+ int total_bytes = data_.GetLength();
+ const uint8_t *const_data = data_.GetConstData();
+
+ *output = StringPrintf("%d bytes:", total_bytes);
+ for (int i = 0; i < total_bytes; ++i) {
+ StringAppendF(output, " 0x%02x", const_data[i]);
+ }
+ return true;
+}
+
+ByteString NetlinkRawAttribute::Encode() const {
+ return NetlinkAttribute::EncodeGeneric(data_.GetConstData(),
+ data_.GetLength());
+}
+
+NetlinkAttributeGeneric::NetlinkAttributeGeneric(int id)
+ : NetlinkRawAttribute(id, "unused-string") {
+ StringAppendF(&id_string_, "<UNKNOWN ATTRIBUTE %d>", id);
+}
+
+const char *NetlinkAttributeGeneric::id_string() const {
+ return id_string_.c_str();
+}
+
+} // namespace shill
diff --git a/netlink_attribute.h b/netlink_attribute.h
new file mode 100644
index 0000000..3dbfa7e
--- /dev/null
+++ b/netlink_attribute.h
@@ -0,0 +1,342 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_NETLINK_ATTRIBUTE_H_
+#define SHILL_NETLINK_ATTRIBUTE_H_
+
+#include <netlink/attr.h>
+
+#include <string>
+
+#include <base/memory/weak_ptr.h>
+
+#include "shill/attribute_list.h"
+#include "shill/byte_string.h"
+#include "shill/logging.h"
+#include "shill/refptr_types.h"
+
+struct nlattr;
+
+namespace shill {
+
+// NetlinkAttribute is an abstract base class that describes an attribute in a
+// netlink-80211 message. Child classes are type-specific and will define
+// Get*Value and Set*Value methods (where * is the type). A second-level of
+// child classes exist for each individual attribute type.
+//
+// An attribute has an id (which is really an enumerated value), a data type,
+// and a value. In an nlattr (the underlying format for an attribute in a
+// message), the data is stored as a blob without type information; the writer
+// and reader of the attribute must agree on the data type.
+class NetlinkAttribute {
+ public:
+ enum Type {
+ kTypeU8,
+ kTypeU16,
+ kTypeU32,
+ kTypeU64,
+ kTypeFlag,
+ kTypeString,
+ kTypeNested,
+ kTypeRaw,
+ kTypeError
+ };
+
+ NetlinkAttribute(int id, const char *id_string,
+ Type datatype, const char *datatype_string);
+ virtual ~NetlinkAttribute() {}
+
+ // Static factories generate the appropriate attribute object from the
+ // raw nlattr data.
+ static NetlinkAttribute *NewControlAttributeFromId(int id);
+ static NetlinkAttribute *NewNl80211AttributeFromId(int id);
+
+ virtual bool InitFromNlAttr(const nlattr *data);
+
+ // Accessors for the attribute's id and datatype information.
+ int id() const { return id_; }
+ virtual const char *id_string() const { return id_string_.c_str(); }
+ Type datatype() const { return datatype_; }
+ const char *datatype_string() const { return datatype_string_; }
+
+ // Accessors. Return false if request is made on wrong type of attribute.
+ virtual bool GetU8Value(uint8_t *value) const;
+ virtual bool SetU8Value(uint8_t new_value);
+
+ virtual bool GetU16Value(uint16_t *value) const;
+ virtual bool SetU16Value(uint16_t value);
+
+ virtual bool GetU32Value(uint32_t *value) const;
+ virtual bool SetU32Value(uint32_t value);
+
+ virtual bool GetU64Value(uint64_t *value) const;
+ virtual bool SetU64Value(uint64_t value);
+
+ virtual bool GetFlagValue(bool *value) const;
+ virtual bool SetFlagValue(bool value);
+
+ virtual bool GetStringValue(std::string *value) const;
+ virtual bool SetStringValue(const std::string value);
+
+ virtual bool GetNestedAttributeList(AttributeListRefPtr *value);
+ virtual bool ConstGetNestedAttributeList(
+ AttributeListConstRefPtr *value) const;
+ virtual bool SetNestedHasAValue();
+
+ virtual bool GetRawValue(ByteString *value) const;
+ virtual bool SetRawValue(const ByteString value);
+
+ // Prints the attribute info -- for debugging.
+ virtual void Print(int log_level, int indent) const;
+
+ // Fill a string with characters that represents the value of the attribute.
+ // If no attribute is found or if the datatype isn't trivially stringizable,
+ // this method returns 'false' and |value| remains unchanged.
+ virtual bool ToString(std::string *value) const = 0;
+
+ // Writes the raw attribute data to a string. For debug.
+ std::string RawToString() const;
+
+ // Encodes the attribute suitably for the attributes in the payload portion
+ // of a netlink message suitable for Sockets::Send. Return value is empty on
+ // failure.
+ virtual ByteString Encode() const = 0;
+
+ bool has_a_value() const { return has_a_value_; }
+
+ // Wrappers for libnl parsers. Needed because, while |nla_get_*| don't
+ // change their arguments, these methods don't declare themselves as 'const'.
+ static char *NlaGetString(const nlattr *input) {
+ return nla_get_string(const_cast<nlattr *>(input));
+ }
+ static uint8_t NlaGetU8(const nlattr *input) {
+ return nla_get_u8(const_cast<nlattr *>(input));
+ }
+ static uint16_t NlaGetU16(const nlattr *input) {
+ return nla_get_u16(const_cast<nlattr *>(input));
+ }
+ static uint32_t NlaGetU32(const nlattr *input) {
+ return nla_get_u32(const_cast<nlattr *>(input));
+ }
+ static uint64_t NlaGetU64(const nlattr *input) {
+ return nla_get_u64(const_cast<nlattr *>(input));
+ }
+
+ protected:
+ // Builds a string to precede a printout of this attribute.
+ std::string HeaderToPrint(int indent) const;
+
+ // Encodes the attribute suitably for the attributes in the payload portion
+ // of a netlink message suitable for Sockets::Send. Return value is empty on
+ // failure.
+ ByteString EncodeGeneric(const unsigned char *data, size_t num_bytes) const;
+
+ // Attribute data (NOT including the nlattr header) corresponding to the
+ // value in any of the child classes.
+ ByteString data_;
+
+ // True if a value has been assigned to the attribute; false, otherwise.
+ bool has_a_value_;
+
+ private:
+ int id_;
+ std::string id_string_;
+ Type datatype_;
+ const char *datatype_string_;
+};
+
+class NetlinkU8Attribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkU8Attribute(int id, const char *id_string)
+ : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
+ virtual bool InitFromNlAttr(const nlattr *data);
+ virtual bool GetU8Value(uint8_t *value) const;
+ virtual bool SetU8Value(uint8_t new_value);
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+
+ private:
+ uint8_t value_;
+};
+
+class NetlinkU16Attribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkU16Attribute(int id, const char *id_string)
+ : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
+ virtual bool InitFromNlAttr(const nlattr *data);
+ virtual bool GetU16Value(uint16_t *value) const;
+ virtual bool SetU16Value(uint16_t new_value);
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+
+ private:
+ uint16_t value_;
+};
+
+class NetlinkU32Attribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkU32Attribute(int id, const char *id_string)
+ : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
+ virtual bool InitFromNlAttr(const nlattr *data);
+ virtual bool GetU32Value(uint32_t *value) const;
+ virtual bool SetU32Value(uint32_t new_value);
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+
+ private:
+ uint32_t value_;
+};
+
+class NetlinkU64Attribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkU64Attribute(int id, const char *id_string)
+ : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
+ virtual bool InitFromNlAttr(const nlattr *data);
+ virtual bool GetU64Value(uint64_t *value) const;
+ virtual bool SetU64Value(uint64_t new_value);
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+
+ private:
+ uint64_t value_;
+};
+
+class NetlinkFlagAttribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkFlagAttribute(int id, const char *id_string)
+ : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
+ virtual bool InitFromNlAttr(const nlattr *data);
+ virtual bool GetFlagValue(bool *value) const;
+ virtual bool SetFlagValue(bool new_value);
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+
+ private:
+ bool value_;
+};
+
+class NetlinkStringAttribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkStringAttribute(int id, const char *id_string)
+ : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
+ virtual bool InitFromNlAttr(const nlattr *data);
+ virtual bool GetStringValue(std::string *value) const;
+ virtual bool SetStringValue(const std::string new_value);
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+
+ private:
+ std::string value_;
+};
+
+class NetlinkNestedAttribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkNestedAttribute(int id, const char *id_string);
+ virtual bool InitFromNlAttr(const nlattr *data) {
+ LOG(FATAL) << "Try initializing a _specific_ nested type, instead.";
+ return false;
+ }
+ virtual bool GetNestedAttributeList(AttributeListRefPtr *value);
+ virtual bool ConstGetNestedAttributeList(
+ AttributeListConstRefPtr *value) const;
+ virtual bool SetNestedHasAValue();
+ virtual void Print(int log_level, int indent) const;
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+
+ protected:
+ // Describes a single nested attribute. Provides the expected values and
+ // type (including further nesting). Normally, an array of these, one for
+ // each attribute at one level of nesting is presented, along with the data
+ // to be parsed, to |InitNestedFromNlAttr|. If the attributes on one level
+ // represent an array, a single |NestedData| is provided and |is_array| is
+ // set (note that one level of nesting either contains _only_ an array or
+ // _no_ array).
+ struct NestedData {
+ nla_policy policy;
+ const char *attribute_name;
+ const NestedData *deeper_nesting;
+ size_t deeper_nesting_size;
+ bool is_array;
+ // TODO(wdg): Add function pointer for a custom attribute parser.
+ };
+
+ // Builds an AttributeList (|list|) that contains all of the attriubtes in
+ // |const_data|. |const_data| should point to the enclosing nested attribute
+ // header; for the example of the nested attribute NL80211_ATTR_CQM:
+ // nlattr::nla_type: NL80211_ATTR_CQM <-- const_data points here
+ // nlattr::nla_len: 12 bytes
+ // nlattr::nla_type: PKT_LOSS_EVENT (1st and only nested attribute)
+ // nlattr::nla_len: 8 bytes
+ // <data>: 0x32
+ // One can assemble (hence, disassemble) a set of child attributes under a
+ // nested attribute parent as an array of elements or as a structure.
+ //
+ // The data is parsed using the expected configuration in |nested_template|.
+ // If the code expects an array, it will pass a single template element and
+ // mark that as an array.
+ static bool InitNestedFromNlAttr(AttributeList *list,
+ const NestedData *nested_template,
+ size_t nested_template_size,
+ const nlattr *const_data);
+
+ static bool ParseNestedArray(AttributeList *list,
+ const NestedData &nested_template,
+ const nlattr *const_data);
+
+ static bool ParseNestedStructure(AttributeList *list,
+ const NestedData *nested_template,
+ size_t nested_template_size,
+ const nlattr *const_data);
+
+ // Helper function used by InitNestedFromNlAttr to add a single child
+ // attribute to a nested attribute.
+ static void AddAttributeToNested(AttributeList *list, uint16_t type, size_t i,
+ const std::string &attribute_name,
+ const nlattr &attr,
+ const NestedData &nested_data);
+ AttributeListRefPtr value_;
+};
+
+class NetlinkRawAttribute : public NetlinkAttribute {
+ public:
+ static const char kMyTypeString[];
+ static const Type kType;
+ NetlinkRawAttribute(int id, const char *id_string)
+ : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
+ virtual bool InitFromNlAttr(const nlattr *data);
+ // Gets the value of the data (the header is not stored).
+ virtual bool GetRawValue(ByteString *value) const;
+ // Should set the value of the data (not the attribute header).
+ virtual bool SetRawValue(const ByteString value);
+ virtual bool ToString(std::string *value) const;
+ virtual ByteString Encode() const;
+};
+
+class NetlinkAttributeGeneric : public NetlinkRawAttribute {
+ public:
+ explicit NetlinkAttributeGeneric(int id);
+ virtual const char *id_string() const;
+
+ private:
+ std::string id_string_;
+};
+
+} // namespace shill
+
+#endif // SHILL_NETLINK_ATTRIBUTE_H_
diff --git a/nl80211_attribute.cc b/nl80211_attribute.cc
index da12040..1216039 100644
--- a/nl80211_attribute.cc
+++ b/nl80211_attribute.cc
@@ -27,919 +27,6 @@
namespace shill {
-// This is a type-corrected copy of |nla_for_each_nested| from libnl.
-#define nla_for_each_nested_type_corrected(pos, nla, rem) \
- for (pos = reinterpret_cast<struct nlattr *>(nla_data(nla)), \
- rem = nla_len(nla); \
- nla_ok(pos, rem); \
- pos = nla_next(pos, &(rem)))
-
-NetlinkAttribute::NetlinkAttribute(int id,
- const char *id_string,
- Type datatype,
- const char *datatype_string)
- : has_a_value_(false), id_(id), id_string_(id_string), datatype_(datatype),
- datatype_string_(datatype_string) {}
-
-// static
-NetlinkAttribute *NetlinkAttribute::NewNl80211AttributeFromId(int id) {
- scoped_ptr<NetlinkAttribute> attr;
- switch (id) {
- case NL80211_ATTR_COOKIE:
- attr.reset(new Nl80211AttributeCookie());
- break;
- case NL80211_ATTR_CQM:
- attr.reset(new Nl80211AttributeCqm());
- break;
- case NL80211_ATTR_DISCONNECTED_BY_AP:
- attr.reset(new Nl80211AttributeDisconnectedByAp());
- break;
- case NL80211_ATTR_DURATION:
- attr.reset(new Nl80211AttributeDuration());
- break;
- case NL80211_ATTR_FRAME:
- attr.reset(new Nl80211AttributeFrame());
- break;
- case NL80211_ATTR_GENERATION:
- attr.reset(new Nl80211AttributeGeneration());
- break;
- case NL80211_ATTR_IFINDEX:
- attr.reset(new Nl80211AttributeIfindex());
- break;
- case NL80211_ATTR_KEY_IDX:
- attr.reset(new Nl80211AttributeKeyIdx());
- break;
- case NL80211_ATTR_KEY_SEQ:
- attr.reset(new Nl80211AttributeKeySeq());
- break;
- case NL80211_ATTR_KEY_TYPE:
- attr.reset(new Nl80211AttributeKeyType());
- break;
- case NL80211_ATTR_MAC:
- attr.reset(new Nl80211AttributeMac());
- break;
- case NL80211_ATTR_REASON_CODE:
- attr.reset(new Nl80211AttributeReasonCode());
- break;
- case NL80211_ATTR_REG_ALPHA2:
- attr.reset(new Nl80211AttributeRegAlpha2());
- break;
- case NL80211_ATTR_REG_INITIATOR:
- attr.reset(new Nl80211AttributeRegInitiator());
- break;
- case NL80211_ATTR_REG_TYPE:
- attr.reset(new Nl80211AttributeRegType());
- break;
- case NL80211_ATTR_RESP_IE:
- attr.reset(new Nl80211AttributeRespIe());
- break;
- case NL80211_ATTR_SCAN_FREQUENCIES:
- attr.reset(new Nl80211AttributeScanFrequencies());
- break;
- case NL80211_ATTR_SCAN_SSIDS:
- attr.reset(new Nl80211AttributeScanSsids());
- break;
- case NL80211_ATTR_STA_INFO:
- attr.reset(new Nl80211AttributeStaInfo());
- break;
- case NL80211_ATTR_STATUS_CODE:
- attr.reset(new Nl80211AttributeStatusCode());
- break;
- case NL80211_ATTR_SUPPORT_MESH_AUTH:
- attr.reset(new Nl80211AttributeSupportMeshAuth());
- break;
- case NL80211_ATTR_TIMED_OUT:
- attr.reset(new Nl80211AttributeTimedOut());
- break;
- case NL80211_ATTR_WIPHY_FREQ:
- attr.reset(new Nl80211AttributeWiphyFreq());
- break;
- case NL80211_ATTR_WIPHY:
- attr.reset(new Nl80211AttributeWiphy());
- break;
- case NL80211_ATTR_WIPHY_NAME:
- attr.reset(new Nl80211AttributeWiphyName());
- break;
- default:
- attr.reset(new NetlinkAttributeGeneric(id));
- break;
- }
- return attr.release();
-}
-
-// Duplicate attribute data, store in map indexed on |id|.
-bool NetlinkAttribute::InitFromNlAttr(const nlattr *other) {
- if (!other) {
- LOG(ERROR) << "NULL data";
- return false;
- }
-
- data_ = ByteString(
- reinterpret_cast<char *>(nla_data(const_cast<nlattr *>(other))),
- nla_len(const_cast<nlattr *>(other)));
- return true;
-}
-
-bool NetlinkAttribute::GetU8Value(uint8_t *value) const {
- LOG(ERROR) << "Attribute is not of type 'U8'";
- return false;
-}
-
-bool NetlinkAttribute::SetU8Value(uint8_t value) {
- LOG(ERROR) << "Attribute is not of type 'U8'";
- return false;
-}
-
-bool NetlinkAttribute::GetU16Value(uint16_t *value) const {
- LOG(ERROR) << "Attribute is not of type 'U16'";
- return false;
-}
-
-bool NetlinkAttribute::SetU16Value(uint16_t value) {
- LOG(ERROR) << "Attribute is not of type 'U16'";
- return false;
-}
-
-bool NetlinkAttribute::GetU32Value(uint32_t *value) const {
- LOG(ERROR) << "Attribute is not of type 'U32'";
- return false;
-}
-
-bool NetlinkAttribute::SetU32Value(uint32_t value) {
- LOG(ERROR) << "Attribute is not of type 'U32'";
- return false;
-}
-
-bool NetlinkAttribute::GetU64Value(uint64_t *value) const {
- LOG(ERROR) << "Attribute is not of type 'U64'";
- return false;
-}
-
-bool NetlinkAttribute::SetU64Value(uint64_t value) {
- LOG(ERROR) << "Attribute is not of type 'U64'";
- return false;
-}
-
-bool NetlinkAttribute::GetFlagValue(bool *value) const {
- LOG(ERROR) << "Attribute is not of type 'Flag'";
- return false;
-}
-
-bool NetlinkAttribute::SetFlagValue(bool value) {
- LOG(ERROR) << "Attribute is not of type 'Flag'";
- return false;
-}
-
-bool NetlinkAttribute::GetStringValue(string *value) const {
- LOG(ERROR) << "Attribute is not of type 'String'";
- return false;
-}
-
-bool NetlinkAttribute::SetStringValue(string value) {
- LOG(ERROR) << "Attribute is not of type 'String'";
- return false;
-}
-
-bool NetlinkAttribute::GetNestedAttributeList(AttributeListRefPtr *value) {
- LOG(ERROR) << "Attribute is not of type 'Nested'";
- return false;
-}
-
-bool NetlinkAttribute::ConstGetNestedAttributeList(
- AttributeListConstRefPtr *value) const {
- LOG(ERROR) << "Attribute is not of type 'Nested'";
- return false;
-}
-
-bool NetlinkAttribute::SetNestedHasAValue() {
- LOG(ERROR) << "Attribute is not of type 'Nested'";
- return false;
-}
-
-bool NetlinkAttribute::GetRawValue(ByteString *value) const {
- LOG(ERROR) << "Attribute is not of type 'Raw'";
- return false;
-}
-
-bool NetlinkAttribute::SetRawValue(const ByteString new_value) {
- LOG(ERROR) << "Attribute is not of type 'Raw'";
- return false;
-}
-
-void NetlinkAttribute::Print(int log_level, int indent) const {
- string attribute_value;
- SLOG(WiFi, log_level) << HeaderToPrint(indent) << " "
- << (ToString(&attribute_value) ? attribute_value :
- "<DOES NOT EXIST>");
-}
-
-string NetlinkAttribute::RawToString() const {
- string output = " === RAW: ";
-
- if (!has_a_value_) {
- StringAppendF(&output, "(empty)");
- return output;
- }
-
- uint16_t length = data_.GetLength();
- const uint8_t *const_data = data_.GetConstData();
-
- StringAppendF(&output, "len=%u", length);
- output.append(" DATA: ");
- for (int i =0 ; i < length; ++i) {
- StringAppendF(&output, "[%d]=%02x ", i, *(const_data)+i);
- }
- output.append(" ==== ");
- return output;
-}
-
-string NetlinkAttribute::HeaderToPrint(int indent) const {
- static const int kSpacesPerIndent = 2;
- return StringPrintf("%*s%s(%d) %s %s=",
- indent * kSpacesPerIndent, "",
- id_string(),
- id(),
- datatype_string(),
- ((has_a_value()) ? "": "UNINITIALIZED "));
-}
-
-ByteString NetlinkAttribute::EncodeGeneric(const unsigned char *data,
- size_t num_bytes) const {
- nlattr header;
- header.nla_type = id();
- header.nla_len = nla_attr_size(num_bytes);
- ByteString result(reinterpret_cast<unsigned char *>(&header), sizeof(header));
- result.Resize(NLA_HDRLEN); // Add padding after the header.
- if (data && (num_bytes != 0)) {
- result.Append(ByteString(data, num_bytes));
- }
- result.Resize(nla_total_size(num_bytes)); // Add padding.
- return result;
-}
-
-// NetlinkU8Attribute
-
-const char NetlinkU8Attribute::kMyTypeString[] = "uint8_t";
-const NetlinkAttribute::Type NetlinkU8Attribute::kType =
- NetlinkAttribute::kTypeU8;
-
-bool NetlinkU8Attribute::InitFromNlAttr(const nlattr *input) {
- if (!input) {
- LOG(ERROR) << "Null |input| parameter";
- return false;
- }
-
- uint8_t data = NlaGetU8(input);
- SetU8Value(data);
- return NetlinkAttribute::InitFromNlAttr(input);
-}
-
-bool NetlinkU8Attribute::GetU8Value(uint8_t *output) const {
- if (!has_a_value_) {
- SLOG(WiFi, 7) << "U8 attribute " << id_string()
- << " hasn't been set to any value.";
- return false;
- }
- if (output) {
- *output = value_;
- }
- return true;
-}
-
-bool NetlinkU8Attribute::SetU8Value(uint8_t new_value) {
- value_ = new_value;
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkU8Attribute::ToString(string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
- uint8_t value;
- if (!GetU8Value(&value))
- return false;
- *output = StringPrintf("%u", value);
- return true;
-}
-
-ByteString NetlinkU8Attribute::Encode() const {
- return NetlinkAttribute::EncodeGeneric(
- reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
-}
-
-
-// NetlinkU16Attribute
-
-const char NetlinkU16Attribute::kMyTypeString[] = "uint16_t";
-const NetlinkAttribute::Type NetlinkU16Attribute::kType =
- NetlinkAttribute::kTypeU16;
-
-bool NetlinkU16Attribute::InitFromNlAttr(const nlattr *input) {
- if (!input) {
- LOG(ERROR) << "Null |input| parameter";
- return false;
- }
-
- uint16_t data = NlaGetU16(input);
- SetU16Value(data);
- return NetlinkAttribute::InitFromNlAttr(input);
-}
-
-bool NetlinkU16Attribute::GetU16Value(uint16_t *output) const {
- if (!has_a_value_) {
- SLOG(WiFi, 7) << "U16 attribute " << id_string()
- << " hasn't been set to any value.";
- return false;
- }
- if (output) {
- *output = value_;
- }
- return true;
-}
-
-bool NetlinkU16Attribute::SetU16Value(uint16_t new_value) {
- value_ = new_value;
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkU16Attribute::ToString(string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
- uint16_t value;
- if (!GetU16Value(&value))
- return false;
- *output = StringPrintf("%u", value);
- return true;
-}
-
-ByteString NetlinkU16Attribute::Encode() const {
- return NetlinkAttribute::EncodeGeneric(
- reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
-}
-
-// NetlinkU32Attribute::
-
-const char NetlinkU32Attribute::kMyTypeString[] = "uint32_t";
-const NetlinkAttribute::Type NetlinkU32Attribute::kType =
- NetlinkAttribute::kTypeU32;
-
-bool NetlinkU32Attribute::InitFromNlAttr(const nlattr *input) {
- if (!input) {
- LOG(ERROR) << "Null |input| parameter";
- return false;
- }
-
- uint32_t data = NlaGetU32(input);
- SetU32Value(data);
- return NetlinkAttribute::InitFromNlAttr(input);
-}
-
-bool NetlinkU32Attribute::GetU32Value(uint32_t *output) const {
- if (!has_a_value_) {
- SLOG(WiFi, 7) << "U32 attribute " << id_string()
- << " hasn't been set to any value.";
- return false;
- }
- if (output) {
- *output = value_;
- }
- return true;
-}
-
-bool NetlinkU32Attribute::SetU32Value(uint32_t new_value) {
- value_ = new_value;
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkU32Attribute::ToString(string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
- uint32_t value;
- if (!GetU32Value(&value))
- return false;
- *output = StringPrintf("%" PRIu32, value);
- return true;
-}
-
-ByteString NetlinkU32Attribute::Encode() const {
- return NetlinkAttribute::EncodeGeneric(
- reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
-}
-
-// NetlinkU64Attribute
-
-const char NetlinkU64Attribute::kMyTypeString[] = "uint64_t";
-const NetlinkAttribute::Type NetlinkU64Attribute::kType =
- NetlinkAttribute::kTypeU64;
-
-bool NetlinkU64Attribute::InitFromNlAttr(const nlattr *input) {
- if (!input) {
- LOG(ERROR) << "Null |input| parameter";
- return false;
- }
-
- uint64_t data = NlaGetU64(input);
- SetU64Value(data);
- return NetlinkAttribute::InitFromNlAttr(input);
-}
-
-bool NetlinkU64Attribute::GetU64Value(uint64_t *output) const {
- if (!has_a_value_) {
- SLOG(WiFi, 7) << "U64 attribute " << id_string()
- << " hasn't been set to any value.";
- return false;
- }
- if (output) {
- *output = value_;
- }
- return true;
-}
-
-bool NetlinkU64Attribute::SetU64Value(uint64_t new_value) {
- value_ = new_value;
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkU64Attribute::ToString(string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
- uint64_t value;
- if (!GetU64Value(&value))
- return false;
- *output = StringPrintf("%" PRIu64, value);
- return true;
-}
-
-ByteString NetlinkU64Attribute::Encode() const {
- return NetlinkAttribute::EncodeGeneric(
- reinterpret_cast<const unsigned char *>(&value_), sizeof(value_));
-}
-
-// NetlinkFlagAttribute
-
-const char NetlinkFlagAttribute::kMyTypeString[] = "flag";
-const NetlinkAttribute::Type NetlinkFlagAttribute::kType =
- NetlinkAttribute::kTypeFlag;
-
-bool NetlinkFlagAttribute::InitFromNlAttr(const nlattr *input) {
- if (!input) {
- LOG(ERROR) << "Null |input| parameter";
- return false;
- }
-
- // The existence of the parameter means it's true
- SetFlagValue(true);
- return NetlinkAttribute::InitFromNlAttr(input);
-}
-
-
-bool NetlinkFlagAttribute::GetFlagValue(bool *output) const {
- if (output) {
- // The lack of the existence of the attribute implies 'false'.
- *output = (has_a_value_) ? value_ : false;
- }
- return true;
-}
-
-bool NetlinkFlagAttribute::SetFlagValue(bool new_value) {
- value_ = new_value;
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkFlagAttribute::ToString(string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
- bool value;
- if (!GetFlagValue(&value))
- return false;
- *output = StringPrintf("%s", value ? "true" : "false");
- return true;
-}
-
-ByteString NetlinkFlagAttribute::Encode() const {
- if (has_a_value_ && value_) {
- return NetlinkAttribute::EncodeGeneric(NULL, 0);
- }
- return ByteString(); // Encoding of nothing implies 'false'.
-}
-
-// NetlinkStringAttribute
-
-const char NetlinkStringAttribute::kMyTypeString[] = "string";
-const NetlinkAttribute::Type NetlinkStringAttribute::kType =
- NetlinkAttribute::kTypeString;
-
-bool NetlinkStringAttribute::InitFromNlAttr(const nlattr *input) {
- if (!input) {
- LOG(ERROR) << "Null |input| parameter";
- return false;
- }
-
- SetStringValue(NlaGetString(input));
- return NetlinkAttribute::InitFromNlAttr(input);
-}
-
-bool NetlinkStringAttribute::GetStringValue(string *output) const {
- if (!has_a_value_) {
- SLOG(WiFi, 7) << "String attribute " << id_string()
- << " hasn't been set to any value.";
- return false;
- }
- if (output) {
- *output = value_;
- }
- return true;
-}
-
-bool NetlinkStringAttribute::SetStringValue(const string new_value) {
- value_ = new_value;
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkStringAttribute::ToString(string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
- string value;
- if (!GetStringValue(&value))
- return false;
-
- *output = StringPrintf("'%s'", value.c_str());
- return true;
-}
-
-ByteString NetlinkStringAttribute::Encode() const {
- return NetlinkAttribute::EncodeGeneric(
- reinterpret_cast<const unsigned char *>(value_.c_str()),
- value_.size() + 1);
-}
-
-// NetlinkNestedAttribute
-
-const char NetlinkNestedAttribute::kMyTypeString[] = "nested";
-const NetlinkAttribute::Type NetlinkNestedAttribute::kType =
- NetlinkAttribute::kTypeNested;
-
-NetlinkNestedAttribute::NetlinkNestedAttribute(int id,
- const char *id_string) :
- NetlinkAttribute(id, id_string, kType, kMyTypeString),
- value_(new AttributeList) {}
-
-ByteString NetlinkNestedAttribute::Encode() const {
- // Encode attribute header.
- nlattr header;
- header.nla_type = id();
- header.nla_len = nla_attr_size(sizeof(header));
- ByteString result(reinterpret_cast<unsigned char *>(&header), sizeof(header));
- result.Resize(NLA_HDRLEN); // Add padding after the header.
-
- // Encode all nested attributes.
- std::map<int, AttributeList::AttributePointer>::const_iterator attribute;
- for (attribute = value_->attributes_.begin();
- attribute != value_->attributes_.end();
- ++attribute) {
- // Each attribute appends appropriate padding so it's not necessary to
- // re-add padding.
- result.Append(attribute->second->Encode());
- }
-
- // Go back and fill-in the size.
- nlattr *new_header = reinterpret_cast<nlattr *>(result.GetData());
- new_header->nla_len = result.GetLength();
-
- return result;
-}
-
-void NetlinkNestedAttribute::Print(int log_level, int indent) const {
- SLOG(WiFi, log_level) << HeaderToPrint(indent);
- value_->Print(log_level, indent + 1);
-}
-
-bool NetlinkNestedAttribute::ToString(std::string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
-
- // This should never be called (attribute->ToString is only called
- // from attribute->Print but NetlinkNestedAttribute::Print doesn't call
- // |ToString|. Still, we should print something in case we got here
- // accidentally.
- LOG(WARNING) << "It is unexpected for this method to be called.";
- output->append("<Nested Attribute>");
- return true;
-}
-
-bool NetlinkNestedAttribute::GetNestedAttributeList(
- AttributeListRefPtr *output) {
- // Not checking |has_a_value| since GetNestedAttributeList is called to get
- // a newly created AttributeList in order to have something to which to add
- // attributes.
- if (output) {
- *output = value_;
- }
- return true;
-}
-
-bool NetlinkNestedAttribute::ConstGetNestedAttributeList(
- AttributeListConstRefPtr *output) const {
- if (!has_a_value_) {
- LOG(ERROR) << "Attribute does not exist.";
- return false;
- }
- if (output) {
- *output = value_;
- }
- return true;
-}
-
-bool NetlinkNestedAttribute::SetNestedHasAValue() {
- has_a_value_ = true;
- return true;
-}
-
-// static
-bool NetlinkNestedAttribute::InitNestedFromNlAttr(
- AttributeList *list,
- const NestedData *nested_template,
- size_t nested_template_size,
- const nlattr *const_data) {
- if (!nested_template) {
- LOG(ERROR) << "Null |nested_template| parameter";
- return false;
- }
- if ((nested_template_size == 1) && (nested_template[0].is_array)) {
- return ParseNestedArray(list, *nested_template, const_data);
- } else {
- return ParseNestedStructure(list, nested_template, nested_template_size,
- const_data);
- }
- return true;
-}
-
-// A nested array provides an arbitrary number of children, all of the same
-// data type. Each array element may be a simple type or may be a structure.
-//
-// static
-bool NetlinkNestedAttribute::ParseNestedArray(
- AttributeList *list,
- const NestedData &array_template,
- const nlattr *const_data) {
- if (!list) {
- LOG(ERROR) << "NULL |list| parameter";
- return false;
- }
- if (!const_data) {
- LOG(ERROR) << "Null |const_data| parameter";
- return false;
- }
- // Casting away constness since |nla_parse_nested| doesn't mark its input as
- // const even though it doesn't modify this input parameter.
- nlattr *attrs = const_cast<nlattr *>(const_data);
-
- struct nlattr *attr;
- int remaining;
- // The |nlattr::nla_type| value for array elements in the provided data may
- // start on any number and are allowed to be discontiguous. In order to
- // skirt writing an iterator, this code replaces the |nla_type| with a
- // contiguous |id|, starting at 1 (note that, while nested structure
- // attributes may not have an |nlattr::nla_type| valued at zero, no such
- // restriction exists for nested array attributes -- this code starts the id
- // at zero in order to be consistent with nested structures).
- //
- // TODO(wdg): Determine whether any code depends on the value of
- // |nlattr::nla_type| for nested array attributes.
- int id = 1;
- nla_for_each_nested_type_corrected(attr, attrs, remaining) {
- string attribute_name = StringPrintf("%s_%d",
- array_template.attribute_name, id);
- AddAttributeToNested(list, array_template.policy.type, id, attribute_name,
- *attr, array_template);
- ++id;
- }
- return true;
-}
-
-// A nested structure provides a fixed set of child attributes (some of
-// which may be optional). The caller provides the expectation of the members
-// and values of a nested structure in the supplied 'policy' template
-// (|struct_template|).
-//
-// static
-bool NetlinkNestedAttribute::ParseNestedStructure(
- AttributeList *list,
- const NestedData *struct_template,
- size_t nested_template_size,
- const nlattr *const_data) {
- if (!list) {
- LOG(ERROR) << "NULL |list| parameter";
- return false;
- }
- if (!struct_template) {
- LOG(ERROR) << "Null |struct_template| parameter";
- return false;
- }
- if (nested_template_size == 0) {
- LOG(ERROR) << "|nested_template_size| parameter is zero";
- return false;
- }
- if (!const_data) {
- LOG(ERROR) << "Null |const_data| parameter";
- return false;
- }
- // Casting away constness since |nla_parse_nested| doesn't mark its input as
- // const even though it doesn't modify this input parameter.
- nlattr *attr_data = const_cast<nlattr *>(const_data);
-
- // |nla_parse_nested| requires an array of |nla_policy|. While an attribute id
- // of zero is illegal, we still need to fill that spot in the policy
- // array so the loop will start at zero.
- scoped_array<nla_policy> policy(new nla_policy[nested_template_size]);
- for (size_t id = 0; id < nested_template_size ; ++id) {
- memcpy(&policy[id], &struct_template[id].policy, sizeof(nla_policy));
- }
-
- // |nla_parse_nested| builds an array of |nlattr| from the input message.
- scoped_array<nlattr *>attr(new nlattr *[nested_template_size]);
- if (nla_parse_nested(attr.get(), nested_template_size-1, attr_data,
- policy.get())) {
- LOG(ERROR) << "nla_parse_nested failed";
- return false;
- }
-
- // Note that the attribute id of zero is illegal so we'll start with id=1.
- for (size_t id = 1; id < nested_template_size; ++id) {
- // Add |attr[id]| if it exists, otherwise, it's a legally omitted optional
- // attribute.
- if (attr[id]) {
- AddAttributeToNested(list, policy[id].type, id,
- struct_template[id].attribute_name, *attr[id],
- struct_template[id]);
- }
- }
- return true;
-}
-
-// static
-void NetlinkNestedAttribute::AddAttributeToNested(
- AttributeList *list, uint16_t type, size_t id, const string &attribute_name,
- const nlattr &attr, const NestedData &nested_template) {
- switch (type) {
- case NLA_UNSPEC:
- list->CreateRawAttribute(id, attribute_name.c_str());
- list->SetRawAttributeValue(id, ByteString(
- reinterpret_cast<const char *>(nla_data(&attr)), nla_len(&attr)));
- break;
- case NLA_U8:
- list->CreateU8Attribute(id, attribute_name.c_str());
- list->SetU8AttributeValue(id, NlaGetU8(&attr));
- break;
- case NLA_U16:
- list->CreateU16Attribute(id, attribute_name.c_str());
- list->SetU16AttributeValue(id, NlaGetU16(&attr));
- break;
- case NLA_U32:
- list->CreateU32Attribute(id, attribute_name.c_str());
- list->SetU32AttributeValue(id, NlaGetU32(&attr));
- break;
- case NLA_U64:
- list->CreateU64Attribute(id, attribute_name.c_str());
- list->SetU64AttributeValue(id, NlaGetU64(&attr));
- break;
- case NLA_FLAG:
- list->CreateFlagAttribute(id, attribute_name.c_str());
- list->SetFlagAttributeValue(id, true);
- break;
- case NLA_STRING:
- // Note that nested structure attributes are validated by |validate_nla|
- // which requires a string attribute to have at least 1 character
- // (presumably for the '\0') while the kernel can create an empty string
- // for at least one nested string array attribute type
- // (NL80211_ATTR_SCAN_SSIDS -- the emptyness of the string is exhibited
- // by the value of |nlattr::nla_len|). This code handles both cases.
- list->CreateStringAttribute(id, attribute_name.c_str());
- if (nla_len(&attr) <= 0) {
- list->SetStringAttributeValue(id, "");
- } else {
- list->SetStringAttributeValue(id, NlaGetString(&attr));
- }
- break;
- case NLA_NESTED:
- {
- if (!nested_template.deeper_nesting) {
- LOG(ERROR) << "No rules for nesting " << attribute_name
- << ". Ignoring.";
- break;
- }
- list->CreateNestedAttribute(id, attribute_name.c_str());
-
- // Now, handle the nested data.
- AttributeListRefPtr nested_attribute;
- if (!list->GetNestedAttributeList(id, &nested_attribute) ||
- !nested_attribute) {
- LOG(FATAL) << "Couldn't get attribute " << attribute_name
- << " which we just created.";
- break;
- }
-
- if (!InitNestedFromNlAttr(nested_attribute.get(),
- nested_template.deeper_nesting,
- nested_template.deeper_nesting_size,
- &attr)) {
- LOG(ERROR) << "Couldn't parse attribute " << attribute_name;
- break;
- }
- list->SetNestedAttributeHasAValue(id);
- }
- break;
- default:
- LOG(ERROR) << "Discarding " << attribute_name
- << ". Attribute has unhandled type " << type << ".";
- break;
- }
-}
-
-// NetlinkRawAttribute
-
-const char NetlinkRawAttribute::kMyTypeString[] = "<raw>";
-const NetlinkAttribute::Type NetlinkRawAttribute::kType =
- NetlinkAttribute::kTypeRaw;
-
-bool NetlinkRawAttribute::InitFromNlAttr(const nlattr *input) {
- if (!input) {
- LOG(ERROR) << "Null |input| parameter";
- return false;
- }
-
- if (!NetlinkAttribute::InitFromNlAttr(input)) {
- return false;
- }
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkRawAttribute::GetRawValue(ByteString *output) const {
- if (!has_a_value_) {
- SLOG(WiFi, 7) << "Raw attribute " << id_string()
- << " hasn't been set to any value.";
- return false;
- }
- if (output) {
- *output = data_;
- }
- return true;
-}
-
-bool NetlinkRawAttribute::SetRawValue(const ByteString new_value) {
- data_ = new_value;
- has_a_value_ = true;
- return true;
-}
-
-bool NetlinkRawAttribute::ToString(string *output) const {
- if (!output) {
- LOG(ERROR) << "Null |output| parameter";
- return false;
- }
- if (!has_a_value_) {
- SLOG(WiFi, 7) << "Raw attribute " << id_string()
- << " hasn't been set to any value.";
- return false;
- }
- int total_bytes = data_.GetLength();
- const uint8_t *const_data = data_.GetConstData();
-
- *output = StringPrintf("%d bytes:", total_bytes);
- for (int i = 0; i < total_bytes; ++i) {
- StringAppendF(output, " 0x%02x", const_data[i]);
- }
- return true;
-}
-
-ByteString NetlinkRawAttribute::Encode() const {
- return NetlinkAttribute::EncodeGeneric(data_.GetConstData(),
- data_.GetLength());
-}
-
-// Specific Attributes.
-
-
const int Nl80211AttributeCookie::kName = NL80211_ATTR_COOKIE;
const char Nl80211AttributeCookie::kNameString[] = "NL80211_ATTR_COOKIE";
@@ -1149,13 +236,4 @@
const int Nl80211AttributeWiphyName::kName = NL80211_ATTR_WIPHY_NAME;
const char Nl80211AttributeWiphyName::kNameString[] = "NL80211_ATTR_WIPHY_NAME";
-NetlinkAttributeGeneric::NetlinkAttributeGeneric(int id)
- : NetlinkRawAttribute(id, "unused-string") {
- StringAppendF(&id_string_, "<UNKNOWN ATTRIBUTE %d>", id);
-}
-
-const char *NetlinkAttributeGeneric::id_string() const {
- return id_string_.c_str();
-}
-
} // namespace shill
diff --git a/nl80211_attribute.h b/nl80211_attribute.h
index b1ace45..9cc197e 100644
--- a/nl80211_attribute.h
+++ b/nl80211_attribute.h
@@ -2,169 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SHILL_NLATTRIBUTE_H_
-#define SHILL_NLATTRIBUTE_H_
+#ifndef SHILL_NL80211_ATTRIBUTE_H_
+#define SHILL_NL80211_ATTRIBUTE_H_
-#include <linux/nl80211.h>
#include <netlink/attr.h>
-#include <netlink/netlink.h>
-#include <map>
-#include <string>
-
-#include "shill/attribute_list.h"
-#include "shill/byte_string.h"
-#include "shill/logging.h"
+#include "shill/netlink_attribute.h"
#include "shill/refptr_types.h"
struct nlattr;
namespace shill {
-// NetlinkAttribute is an abstract base class that describes an attribute in a
-// netlink-80211 message. Child classes are type-specific and will define
-// Get*Value and Set*Value methods (where * is the type). A second-level of
-// child classes exist for each individual attribute type.
-//
-// An attribute has an id (which is really an enumerated value), a data type,
-// and a value. In an nlattr (the underlying format for an attribute in a
-// message), the data is stored as a blob without type information; the writer
-// and reader of the attribute must agree on the data type.
-class NetlinkAttribute {
- public:
- enum Type {
- kTypeU8,
- kTypeU16,
- kTypeU32,
- kTypeU64,
- kTypeFlag,
- kTypeString,
- kTypeNested,
- kTypeRaw,
- kTypeError
- };
-
- NetlinkAttribute(int id, const char *id_string,
- Type datatype, const char *datatype_string);
- virtual ~NetlinkAttribute() {}
-
- virtual bool InitFromNlAttr(const nlattr *data);
-
- // Accessors for the attribute's id and datatype information.
- int id() const { return id_; }
- virtual const char *id_string() const { return id_string_.c_str(); }
- Type datatype() const { return datatype_; }
- const char *datatype_string() const { return datatype_string_; }
-
- // Accessors. Return false if request is made on wrong type of attribute.
- virtual bool GetU8Value(uint8_t *value) const;
- virtual bool SetU8Value(uint8_t new_value);
-
- virtual bool GetU16Value(uint16_t *value) const;
- virtual bool SetU16Value(uint16_t value);
-
- virtual bool GetU32Value(uint32_t *value) const;
- virtual bool SetU32Value(uint32_t value);
-
- virtual bool GetU64Value(uint64_t *value) const;
- virtual bool SetU64Value(uint64_t value);
-
- virtual bool GetFlagValue(bool *value) const;
- virtual bool SetFlagValue(bool value);
-
- virtual bool GetStringValue(std::string *value) const;
- virtual bool SetStringValue(const std::string value);
-
- virtual bool GetNestedAttributeList(AttributeListRefPtr *value);
- virtual bool ConstGetNestedAttributeList(
- AttributeListConstRefPtr *value) const;
- virtual bool SetNestedHasAValue();
-
- virtual bool GetRawValue(ByteString *value) const;
- virtual bool SetRawValue(const ByteString value);
-
- // Prints the attribute info -- for debugging.
- virtual void Print(int log_level, int indent) const;
-
- // Fill a string with characters that represents the value of the attribute.
- // If no attribute is found or if the datatype isn't trivially stringizable,
- // this method returns 'false' and |value| remains unchanged.
- virtual bool ToString(std::string *value) const = 0;
-
- // Writes the raw attribute data to a string. For debug.
- std::string RawToString() const;
-
- // Encodes the attribute suitably for the attributes in the payload portion
- // of a netlink message suitable for Sockets::Send. Return value is empty on
- // failure.
- virtual ByteString Encode() const = 0;
-
- bool has_a_value() const { return has_a_value_; }
-
- // Wrappers for libnl parsers. Needed because, while |nla_get_*| don't
- // change their arguments, these methods don't declare themselves as 'const'.
- static char *NlaGetString(const nlattr *input) {
- return nla_get_string(const_cast<nlattr *>(input));
- }
- static uint8_t NlaGetU8(const nlattr *input) {
- return nla_get_u8(const_cast<nlattr *>(input));
- }
- static uint16_t NlaGetU16(const nlattr *input) {
- return nla_get_u16(const_cast<nlattr *>(input));
- }
- static uint32_t NlaGetU32(const nlattr *input) {
- return nla_get_u32(const_cast<nlattr *>(input));
- }
- static uint64_t NlaGetU64(const nlattr *input) {
- return nla_get_u64(const_cast<nlattr *>(input));
- }
-
- // Static factories generate the appropriate attribute object from the
- // raw nlattr data.
- static NetlinkAttribute *NewControlAttributeFromId(int id);
- static NetlinkAttribute *NewNl80211AttributeFromId(int id);
-
- protected:
- // Builds a string to precede a printout of this attribute.
- std::string HeaderToPrint(int indent) const;
-
- // Encodes the attribute suitably for the attributes in the payload portion
- // of a netlink message suitable for Sockets::Send. Return value is empty on
- // failure.
- ByteString EncodeGeneric(const unsigned char *data, size_t num_bytes) const;
-
- // Attribute data (NOT including the nlattr header) corresponding to the
- // value in any of the child classes.
- ByteString data_;
-
- // True if a value has been assigned to the attribute; false, otherwise.
- bool has_a_value_;
-
- private:
- int id_;
- std::string id_string_;
- Type datatype_;
- const char *datatype_string_;
-};
-
// U8.
-class NetlinkU8Attribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkU8Attribute(int id, const char *id_string)
- : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
- virtual bool InitFromNlAttr(const nlattr *data);
- virtual bool GetU8Value(uint8_t *value) const;
- virtual bool SetU8Value(uint8_t new_value);
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-
- private:
- uint8_t value_;
-};
-
class Nl80211AttributeKeyIdx : public NetlinkU8Attribute {
public:
static const int kName;
@@ -181,22 +32,6 @@
// U16.
-class NetlinkU16Attribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkU16Attribute(int id, const char *id_string)
- : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
- virtual bool InitFromNlAttr(const nlattr *data);
- virtual bool GetU16Value(uint16_t *value) const;
- virtual bool SetU16Value(uint16_t new_value);
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-
- private:
- uint16_t value_;
-};
-
class Nl80211AttributeReasonCode : public NetlinkU16Attribute {
public:
static const int kName;
@@ -213,22 +48,6 @@
// U32.
-class NetlinkU32Attribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkU32Attribute(int id, const char *id_string)
- : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
- virtual bool InitFromNlAttr(const nlattr *data);
- virtual bool GetU32Value(uint32_t *value) const;
- virtual bool SetU32Value(uint32_t new_value);
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-
- private:
- uint32_t value_;
-};
-
class Nl80211AttributeDuration : public NetlinkU32Attribute {
public:
static const int kName;
@@ -280,22 +99,6 @@
// U64.
-class NetlinkU64Attribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkU64Attribute(int id, const char *id_string)
- : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
- virtual bool InitFromNlAttr(const nlattr *data);
- virtual bool GetU64Value(uint64_t *value) const;
- virtual bool SetU64Value(uint64_t new_value);
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-
- private:
- uint64_t value_;
-};
-
class Nl80211AttributeCookie : public NetlinkU64Attribute {
public:
static const int kName;
@@ -305,22 +108,6 @@
// Flag.
-class NetlinkFlagAttribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkFlagAttribute(int id, const char *id_string)
- : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
- virtual bool InitFromNlAttr(const nlattr *data);
- virtual bool GetFlagValue(bool *value) const;
- virtual bool SetFlagValue(bool new_value);
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-
- private:
- bool value_;
-};
-
class Nl80211AttributeDisconnectedByAp : public NetlinkFlagAttribute {
public:
static const int kName;
@@ -346,22 +133,6 @@
// String.
-class NetlinkStringAttribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkStringAttribute(int id, const char *id_string)
- : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
- virtual bool InitFromNlAttr(const nlattr *data);
- virtual bool GetStringValue(std::string *value) const;
- virtual bool SetStringValue(const std::string new_value);
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-
- private:
- std::string value_;
-};
-
class Nl80211AttributeRegAlpha2 : public NetlinkStringAttribute {
public:
static const int kName;
@@ -378,77 +149,6 @@
// Nested.
-class NetlinkNestedAttribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkNestedAttribute(int id, const char *id_string);
- virtual bool InitFromNlAttr(const nlattr *data) {
- LOG(FATAL) << "Try initializing a _specific_ nested type, instead.";
- return false;
- }
- virtual bool GetNestedAttributeList(AttributeListRefPtr *value);
- virtual bool ConstGetNestedAttributeList(
- AttributeListConstRefPtr *value) const;
- virtual bool SetNestedHasAValue();
- virtual void Print(int log_level, int indent) const;
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-
- protected:
- // Describes a single nested attribute. Provides the expected values and
- // type (including further nesting). Normally, an array of these, one for
- // each attribute at one level of nesting is presented, along with the data
- // to be parsed, to |InitNestedFromNlAttr|. If the attributes on one level
- // represent an array, a single |NestedData| is provided and |is_array| is
- // set (note that one level of nesting either contains _only_ an array or
- // _no_ array).
- struct NestedData {
- nla_policy policy;
- const char *attribute_name;
- const NestedData *deeper_nesting;
- size_t deeper_nesting_size;
- bool is_array;
- // TODO(wdg): Add function pointer for a custom attribute parser.
- };
-
- // Builds an AttributeList (|list|) that contains all of the attriubtes in
- // |const_data|. |const_data| should point to the enclosing nested attribute
- // header; for the example of the nested attribute NL80211_ATTR_CQM:
- // nlattr::nla_type: NL80211_ATTR_CQM <-- const_data points here
- // nlattr::nla_len: 12 bytes
- // nlattr::nla_type: PKT_LOSS_EVENT (1st and only nested attribute)
- // nlattr::nla_len: 8 bytes
- // <data>: 0x32
- // One can assemble (hence, disassemble) a set of child attributes under a
- // nested attribute parent as an array of elements or as a structure.
- //
- // The data is parsed using the expected configuration in |nested_template|.
- // If the code expects an array, it will pass a single template element and
- // mark that as an array.
- static bool InitNestedFromNlAttr(AttributeList *list,
- const NestedData *nested_template,
- size_t nested_template_size,
- const nlattr *const_data);
-
- static bool ParseNestedArray(AttributeList *list,
- const NestedData &nested_template,
- const nlattr *const_data);
-
- static bool ParseNestedStructure(AttributeList *list,
- const NestedData *nested_template,
- size_t nested_template_size,
- const nlattr *const_data);
-
- // Helper function used by InitNestedFromNlAttr to add a single child
- // attribute to a nested attribute.
- static void AddAttributeToNested(AttributeList *list, uint16_t type, size_t i,
- const std::string &attribute_name,
- const nlattr &attr,
- const NestedData &nested_data);
- AttributeListRefPtr value_;
-};
-
class Nl80211AttributeCqm : public NetlinkNestedAttribute {
public:
static const int kName;
@@ -483,21 +183,6 @@
// Raw.
-class NetlinkRawAttribute : public NetlinkAttribute {
- public:
- static const char kMyTypeString[];
- static const Type kType;
- NetlinkRawAttribute(int id, const char *id_string)
- : NetlinkAttribute(id, id_string, kType, kMyTypeString) {}
- virtual bool InitFromNlAttr(const nlattr *data);
- // Gets the value of the data (the header is not stored).
- virtual bool GetRawValue(ByteString *value) const;
- // Should set the value of the data (not the attribute header).
- virtual bool SetRawValue(const ByteString value);
- virtual bool ToString(std::string *value) const;
- virtual ByteString Encode() const;
-};
-
class Nl80211AttributeFrame : public NetlinkRawAttribute {
public:
static const int kName;
@@ -505,15 +190,6 @@
Nl80211AttributeFrame() : NetlinkRawAttribute(kName, kNameString) {}
};
-class NetlinkAttributeGeneric : public NetlinkRawAttribute {
- public:
- explicit NetlinkAttributeGeneric(int id);
- virtual const char *id_string() const;
-
- private:
- std::string id_string_;
-};
-
class Nl80211AttributeKeySeq : public NetlinkRawAttribute {
public:
static const int kName;
diff --git a/nl80211_message.cc b/nl80211_message.cc
index 34381e0..fe60011 100644
--- a/nl80211_message.cc
+++ b/nl80211_message.cc
@@ -49,8 +49,8 @@
#include "shill/attribute_list.h"
#include "shill/ieee80211.h"
#include "shill/logging.h"
+#include "shill/netlink_attribute.h"
#include "shill/netlink_socket.h"
-#include "shill/nl80211_attribute.h"
#include "shill/scope_logger.h"
#include "shill/wifi.h"