shill: Configures netlink broadcast messaging with raw sockets.
This CL provides an interface for software to request the netlink
message_type and available multicast groups corresponding to a netlink
family name. The new software completely replaces the old event_type
stuff that utilized libnl to get this information (and, as such, it is
the last nail in the coffin of using libnl for netlink communication
with the kernel). |NetlinkMessage|s now get their message_type from
Config80211.
Also includes code to handle multi-part responses to a netlink message.
BUG=chromium:218211
TEST=unittests and manual tests. The manual tests consist of:
- Start shill with log=-10/wifi. On the target, in a shell window,
do the following:
o stop shill
o shill --log-level=-10 --log-scopes=wifi
- Wait five seconds (the code will do everything it needs to at
startup).
- Look in /var/log/net.log and verify the following:
o a CTRL_CMD_GETFAMILY message is sent to the kernel (just search
for the 'CTRL_CMD_GETFAMILY' string.
o a CTRL_CMD_NEWFAMILY message is received from the kernel
o after those messages, verify that one or more
NL80211_CMD_TRIGGER_SCAN messages received from the kernel.
Change-Id: I04571bdff9908ad8bd39a3a64a24e7e11074bf18
Reviewed-on: https://gerrit.chromium.org/gerrit/44770
Commit-Queue: Wade Guthrie <wdg@chromium.org>
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
diff --git a/nl80211_message.cc b/nl80211_message.cc
index d9df420..99646f3 100644
--- a/nl80211_message.cc
+++ b/nl80211_message.cc
@@ -78,15 +78,19 @@
const char Nl80211Message::kBogusMacAddress[] = "XX:XX:XX:XX:XX:XX";
const unsigned int Nl80211Message::kEthernetAddressBytes = 6;
+const char Nl80211Message::kMessageTypeString[] = "nl80211";
map<uint16_t, string> *Nl80211Message::reason_code_string_ = NULL;
map<uint16_t, string> *Nl80211Message::status_code_string_ = NULL;
uint16_t Nl80211Message::nl80211_message_type_ = kIllegalMessageType;
// NetlinkMessage
-ByteString NetlinkMessage::EncodeHeader(uint32_t sequence_number,
- uint16_t nlmsg_type) {
+ByteString NetlinkMessage::EncodeHeader(uint32_t sequence_number) {
ByteString result;
+ if (message_type_ == kIllegalMessageType) {
+ LOG(ERROR) << "Message type not set";
+ return result;
+ }
sequence_number_ = sequence_number;
if (sequence_number_ == kBroadcastSequenceNumber) {
LOG(ERROR) << "Couldn't get a legal sequence number";
@@ -97,7 +101,7 @@
nlmsghdr header;
size_t nlmsghdr_with_pad = NLMSG_ALIGN(sizeof(header));
header.nlmsg_len = nlmsghdr_with_pad;
- header.nlmsg_type = nlmsg_type;
+ header.nlmsg_type = message_type_;
header.nlmsg_flags = NLM_F_REQUEST | flags_;
header.nlmsg_seq = sequence_number_;
header.nlmsg_pid = getpid();
@@ -210,8 +214,7 @@
return true;
}
-ByteString ErrorAckMessage::Encode(uint32_t sequence_number,
- uint16_t nlmsg_type) {
+ByteString ErrorAckMessage::Encode(uint32_t sequence_number) {
LOG(ERROR) << "We're not supposed to send errors or Acks to the kernel";
return ByteString();
}
@@ -233,7 +236,7 @@
const uint16_t NoopMessage::kMessageType = NLMSG_NOOP;
-ByteString NoopMessage::Encode(uint32_t sequence_number, uint16_t nlmsg_type) {
+ByteString NoopMessage::Encode(uint32_t sequence_number) {
LOG(ERROR) << "We're not supposed to send NOOP to the kernel";
return ByteString();
}
@@ -244,7 +247,7 @@
const uint16_t DoneMessage::kMessageType = NLMSG_DONE;
-ByteString DoneMessage::Encode(uint32_t sequence_number, uint16_t nlmsg_type) {
+ByteString DoneMessage::Encode(uint32_t sequence_number) {
LOG(ERROR)
<< "We're not supposed to send Done messages (are we?) to the kernel";
return ByteString();
@@ -256,8 +259,7 @@
const uint16_t OverrunMessage::kMessageType = NLMSG_OVERRUN;
-ByteString OverrunMessage::Encode(uint32_t sequence_number,
- uint16_t nlmsg_type) {
+ByteString OverrunMessage::Encode(uint32_t sequence_number) {
LOG(ERROR) << "We're not supposed to send Overruns to the kernel";
return ByteString();
}
@@ -268,10 +270,9 @@
// GenericNetlinkMessage
-ByteString GenericNetlinkMessage::EncodeHeader(uint32_t sequence_number,
- uint16_t nlmsg_type) {
+ByteString GenericNetlinkMessage::EncodeHeader(uint32_t sequence_number) {
// Build nlmsghdr.
- ByteString result(NetlinkMessage::EncodeHeader(sequence_number, nlmsg_type));
+ ByteString result(NetlinkMessage::EncodeHeader(sequence_number));
if (result.GetLength() == 0) {
LOG(ERROR) << "Couldn't encode message header.";
return result;
@@ -294,9 +295,8 @@
return result;
}
-ByteString GenericNetlinkMessage::Encode(uint32_t sequence_number,
- uint16_t nlmsg_type) {
- ByteString result(EncodeHeader(sequence_number, nlmsg_type));
+ByteString GenericNetlinkMessage::Encode(uint32_t sequence_number) {
+ ByteString result(EncodeHeader(sequence_number));
if (result.GetLength() == 0) {
LOG(ERROR) << "Couldn't encode message header.";
return result;
@@ -344,6 +344,14 @@
// Nl80211Message
+// static
+void Nl80211Message::SetMessageType(uint16_t message_type) {
+ if (message_type == NetlinkMessage::kIllegalMessageType) {
+ LOG(FATAL) << "Absolutely need a legal message type for Nl80211 messages.";
+ }
+ nl80211_message_type_ = message_type;
+}
+
bool Nl80211Message::InitFromNlmsg(const nlmsghdr *const_msg) {
if (!const_msg) {
LOG(ERROR) << "Null |msg| parameter";
@@ -570,7 +578,6 @@
return true;
}
-
// Helper function to provide a string for a MAC address.
bool Nl80211Message::GetMacAttributeString(int id, string *value) const {
if (!value) {