shill: Add type-specific children of Nl80211Attribute type.
This checkin adds all the type-specific children of the Nl80211Attribute
type without actually changing any of the code that's called (that's
planned for a later checkin).
The next checkin includes all the attributes necessary to use
Nl80211Attribute. After that, we'll go for the functionality changes
(which, BTW, passes unittests).
BUG=chromium-os:36637
TEST=unittests.
Change-Id: Ib3944e3b18faeec322ea93cd989daa9bbeb0c0c7
Reviewed-on: https://gerrit.chromium.org/gerrit/39319
Commit-Ready: Wade Guthrie <wdg@chromium.org>
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
diff --git a/user_bound_nlmessage.cc b/user_bound_nlmessage.cc
index 9fce829..e822316 100644
--- a/user_bound_nlmessage.cc
+++ b/user_bound_nlmessage.cc
@@ -28,9 +28,9 @@
#include <endian.h>
#include <errno.h>
-#include <netinet/in.h>
#include <linux/nl80211.h>
#include <net/if.h>
+#include <netinet/in.h>
#include <netlink/attr.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/family.h>
@@ -47,6 +47,7 @@
#include "shill/ieee80211.h"
#include "shill/logging.h"
+#include "shill/nl80211_attribute.h"
#include "shill/scope_logger.h"
using base::LazyInstance;
@@ -69,7 +70,7 @@
const uint8_t Nl80211Frame::kFrameTypeMask = 0xfc;
const uint32_t UserBoundNlMessage::kIllegalMessage = 0xFFFFFFFF;
-const int UserBoundNlMessage::kEthernetAddressBytes = 6;
+const unsigned int UserBoundNlMessage::kEthernetAddressBytes = 6;
map<uint16_t, string> *UserBoundNlMessage::reason_code_string_ = NULL;
map<uint16_t, string> *UserBoundNlMessage::status_code_string_ = NULL;
@@ -383,23 +384,18 @@
// Returns the raw attribute data but not the header.
bool UserBoundNlMessage::GetRawAttributeData(enum nl80211_attrs name,
- void **value,
- int *length) const {
+ ByteString *value) const {
if (!value) {
LOG(ERROR) << "Null |value| parameter";
return false;
}
-
const nlattr *attr = GetAttribute(name);
if (!attr) {
- *value = NULL;
+ value->Clear();
return false;
}
-
- if (length) {
- *length = nla_len(attr);
- }
- *value = nla_data(attr);
+ *value = ByteString(reinterpret_cast<unsigned char *>(nla_data(attr)),
+ nla_len(attr));
return true;
}
@@ -415,7 +411,7 @@
return false;
}
- value->assign(nla_get_string(const_cast<nlattr *>(attr)));
+ value->assign(Nl80211Attribute::NlaGetString(attr));
return true;
}
@@ -431,7 +427,7 @@
return false;
}
- *value = nla_get_u8(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU8(attr);
return true;
}
@@ -447,7 +443,7 @@
return false;
}
- *value = nla_get_u16(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU16(attr);
return true;
}
@@ -463,7 +459,7 @@
return false;
}
- *value = nla_get_u32(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU32(attr);
return true;
}
@@ -479,7 +475,7 @@
return false;
}
- *value = nla_get_u64(const_cast<nlattr *>(attr));
+ *value = Nl80211Attribute::NlaGetU64(attr);
return true;
}
@@ -491,13 +487,12 @@
return false;
}
- void *rawdata_void = NULL;
- if (!GetRawAttributeData(name, &rawdata_void, NULL)) {
+ ByteString data;
+ if (!GetRawAttributeData(name, &data)) {
value->assign(kBogusMacAddress);
return false;
}
- const uint8_t *rawdata = reinterpret_cast<const uint8_t *>(rawdata_void);
- value->assign(StringFromMacAddress(rawdata));
+ value->assign(StringFromMacAddress(data.GetConstData()));
return true;
}
@@ -512,20 +507,21 @@
value->clear();
if (AttributeExists(name)) {
- void *rawdata = NULL;
- int len = 0;
- if (GetRawAttributeData(name, &rawdata, &len) && rawdata) {
+ ByteString rawdata;
+ if (GetRawAttributeData(name, &rawdata) && !rawdata.IsEmpty()) {
nlattr *nst = NULL;
- nlattr *attr_data = reinterpret_cast<nlattr *>(rawdata);
+ // |nla_for_each_attr| requires a non-const parameter even though it
+ // doesn't change the data.
+ nlattr *attr_data = reinterpret_cast<nlattr *>(rawdata.GetData());
int rem_nst;
+ int len = rawdata.GetLength();
nla_for_each_attr(nst, attr_data, len, rem_nst) {
- value->push_back(nla_get_u32(nst));
+ value->push_back(Nl80211Attribute::NlaGetU32(nst));
}
}
return true;
}
-
return false;
}
@@ -538,12 +534,14 @@
}
if (AttributeExists(name)) {
- void *rawdata = NULL;
- int len = 0;
- if (GetRawAttributeData(name, &rawdata, &len) && rawdata) {
+ ByteString rawdata;
+ if (GetRawAttributeData(name, &rawdata) && !rawdata.IsEmpty()) {
nlattr *nst = NULL;
- nlattr *data = reinterpret_cast<nlattr *>(rawdata);
+ // |nla_for_each_attr| requires a non-const parameter even though it
+ // doesn't change the data.
+ nlattr *data = reinterpret_cast<nlattr *>(rawdata.GetData());
int rem_nst;
+ int len = rawdata.GetLength();
nla_for_each_attr(nst, data, len, rem_nst) {
value->push_back(StringFromSsid(nla_len(nst),
@@ -553,7 +551,6 @@
}
return true;
}
-
return false;
}
@@ -980,7 +977,7 @@
const nlattr *UserBoundNlMessage::GetAttribute(enum nl80211_attrs name)
const {
- map<enum nl80211_attrs, nlattr *>::const_iterator match;
+ map<nl80211_attrs, nlattr *>::const_iterator match;
match = attributes_.find(name);
// This method may be called to explore the existence of the attribute so
// we'll not emit an error if it's not found.
@@ -1015,13 +1012,9 @@
string UserBoundNlMessage::StringFromFrame(enum nl80211_attrs attr_name) const {
string output;
-
- void *rawdata = NULL;
- int frame_byte_count = 0;
- if (GetRawAttributeData(attr_name, &rawdata, &frame_byte_count) && rawdata) {
- const uint8_t *frame_data = reinterpret_cast<const uint8_t *>(rawdata);
-
- Nl80211Frame frame(frame_data, frame_byte_count);
+ ByteString frame_data;
+ if (GetRawAttributeData(attr_name, &frame_data) && !frame_data.IsEmpty()) {
+ Nl80211Frame frame(frame_data);
frame.ToString(&output);
} else {
output.append(" [no frame]");
@@ -1054,7 +1047,7 @@
} else {
StringAppendF(&output, "%02x", arg[0]);
- for (int i = 1; i < kEthernetAddressBytes ; ++i) {
+ for (unsigned int i = 1; i < kEthernetAddressBytes ; ++i) {
StringAppendF(&output, ":%02x", arg[i]);
}
}
@@ -1131,20 +1124,15 @@
return match->second;
}
-Nl80211Frame::Nl80211Frame(const uint8_t *raw_frame, int frame_byte_count)
+Nl80211Frame::Nl80211Frame(const ByteString &raw_frame)
: frame_type_(kIllegalFrameType), reason_(UINT16_MAX), status_(UINT16_MAX),
- frame_(0), byte_count_(0) {
- if (raw_frame == NULL)
- return;
-
- frame_ = new uint8_t[frame_byte_count];
- memcpy(frame_, raw_frame, frame_byte_count);
- byte_count_ = frame_byte_count;
+ frame_(raw_frame) {
const IEEE_80211::ieee80211_frame *frame =
- reinterpret_cast<const IEEE_80211::ieee80211_frame *>(frame_);
+ reinterpret_cast<const IEEE_80211::ieee80211_frame *>(
+ frame_.GetConstData());
// Now, let's populate the other stuff.
- if (frame_byte_count >= kMinimumFrameByteCount) {
+ if (frame_.GetLength() >= kMinimumFrameByteCount) {
mac_from_ =
UserBoundNlMessage::StringFromMacAddress(&frame->destination_mac[0]);
mac_to_ = UserBoundNlMessage::StringFromMacAddress(&frame->source_mac[0]);
@@ -1171,28 +1159,23 @@
}
}
-Nl80211Frame::~Nl80211Frame() {
- delete [] frame_;
- frame_ = NULL;
-}
-
bool Nl80211Frame::ToString(string *output) const {
if (!output) {
LOG(ERROR) << "NULL |output|";
return false;
}
- if ((byte_count_ == 0) || (frame_ == reinterpret_cast<uint8_t *>(NULL))) {
+ if (frame_.IsEmpty()) {
output->append(" [no frame]");
return true;
}
- if (byte_count_ < kMinimumFrameByteCount) {
+ if (frame_.GetLength() < kMinimumFrameByteCount) {
output->append(" [invalid frame: ");
} else {
StringAppendF(output, " %s -> %s", mac_from_.c_str(), mac_to_.c_str());
- switch (frame_[0] & kFrameTypeMask) {
+ switch (frame_.GetConstData()[0] & kFrameTypeMask) {
case kAssocResponseFrameType:
StringAppendF(output, "; AssocResponse status: %u: %s",
status_,
@@ -1226,8 +1209,9 @@
output->append(" [frame: ");
}
- for (int i = 0; i < byte_count_; ++i) {
- StringAppendF(output, "%02x, ", frame_[i]);
+ const unsigned char *frame = frame_.GetConstData();
+ for (size_t i = 0; i < frame_.GetLength(); ++i) {
+ StringAppendF(output, "%02x, ", frame[i]);
}
output->append("]");
@@ -1235,17 +1219,7 @@
}
bool Nl80211Frame::IsEqual(const Nl80211Frame &other) const {
- if (byte_count_ != other.byte_count_) {
- return false;
- }
-
- for (int i = 0; i < byte_count_; ++i) {
- if (frame_[i] != other.frame_[i]) {
- return false;
- }
- }
-
- return true;
+ return frame_.Equals(other.frame_);
}
@@ -1418,12 +1392,10 @@
}
if (AttributeExists(NL80211_ATTR_KEY_SEQ)) {
- void *rawdata = NULL;
- int length = 0;
- if (GetRawAttributeData(NL80211_ATTR_KEY_SEQ, &rawdata, &length) &&
- rawdata && length == 6) {
- const unsigned char *seq = reinterpret_cast<const unsigned char *>(
- rawdata);
+ ByteString rawdata;
+ if (GetRawAttributeData(NL80211_ATTR_KEY_SEQ, &rawdata) &&
+ rawdata.GetLength() == UserBoundNlMessage::kEthernetAddressBytes) {
+ const unsigned char *seq = rawdata.GetConstData();
StringAppendF(&output, " seq=%02x%02x%02x%02x%02x%02x",
seq[0], seq[1], seq[2], seq[3], seq[4], seq[5]);
}
@@ -1518,6 +1490,8 @@
output.append("connection quality monitor event: ");
const nlattr *const_data = GetAttribute(NL80211_ATTR_CQM);
+ // Note that |nla_parse_nested| doesn't change |const_data| but doesn't
+ // declare itself as 'const', either. Hence the cast.
nlattr *cqm_attr = const_cast<nlattr *>(const_data);
nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
@@ -1530,7 +1504,8 @@
if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]) {
enum nl80211_cqm_rssi_threshold_event rssi_event =
static_cast<enum nl80211_cqm_rssi_threshold_event>(
- nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]));
+ Nl80211Attribute::NlaGetU32(
+ cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]));
if (rssi_event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)
output.append("RSSI went above threshold");
else
@@ -1541,11 +1516,11 @@
GetMacAttributeString(NL80211_ATTR_MAC, &mac);
StringAppendF(&output, "peer %s didn't ACK %" PRIu32 " packets",
mac.c_str(),
- nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]));
+ Nl80211Attribute::NlaGetU32(
+ cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]));
} else {
output.append("unknown event");
}
-
return output;
}
@@ -1620,13 +1595,16 @@
nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
+ // Note that |nla_parse_nested| doesn't change its parameters but doesn't
+ // declare itself as 'const', either. Hence the cast.
if (nla_parse_nested(tb_freq,
NL80211_FREQUENCY_ATTR_MAX,
const_cast<nlattr *>(tb),
const_cast<nla_policy *>(kBeaconFreqPolicy)))
return -EINVAL;
- chan->center_freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
+ chan->center_freq = Nl80211Attribute::NlaGetU32(
+ tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN])
chan->passive_scan = true;
@@ -1922,7 +1900,7 @@
// Parse the attributes from the nl message payload (which starts at the
// header) into the 'tb' array.
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
- genlmsg_attrlen(gnlh, 0), NULL);
+ genlmsg_attrlen(gnlh, 0), NULL);
if (!message->Init(tb, msg)) {
LOG(ERROR) << "Message did not initialize properly";