shill: Adds new message types.

Added the CTRL_CMD family of messages which includes CTRL_CMD_GET_FAMILY
and its response, CTRL_CMD_NEW_FAMILY.  These will be needed when we go
to get rid of libnl.

A few message types (NLMSG_NOOP; NLMSG_ERROR, which also include Acks;
NLMSG_DONE; and NLMSG_OVERRUN) are supported at the base level of the
netlink protocol.  These types were added (which required moving error,
ack, and noop messages from their previously erroneous spot as part of
nl80211 messages).

The NL80211_CMD_GET_SCAN message was added in anticipation of supporting
scan inside shill.

As part of all of this, |NetlinkMessageFactory::CreateMessage| was
cleaned-up.

BUG=None.
TEST=unittests and manual tests (started shill with log-level=-10,wifi
and saw that shill is receiving and decoding messages).

Change-Id: Iddcec54d8f8b47231e25719cbeb778aff9fd971c
Reviewed-on: https://gerrit.chromium.org/gerrit/44645
Reviewed-by: Wade Guthrie <wdg@chromium.org>
Tested-by: Wade Guthrie <wdg@chromium.org>
Commit-Queue: Wade Guthrie <wdg@chromium.org>
diff --git a/nl80211_message.h b/nl80211_message.h
index 3ecc022..6d2f740 100644
--- a/nl80211_message.h
+++ b/nl80211_message.h
@@ -120,6 +120,73 @@
   DISALLOW_COPY_AND_ASSIGN(NetlinkMessage);
 };
 
+
+// The Error and Ack messages are received from the kernel and are combined,
+// here, because they look so much alike (the only difference is that the
+// error code is 0 for the Ack messages).  Error messages are received from
+// the kernel in response to a sent message when there's a problem (such as
+// a malformed message or a busy kernel module).  Ack messages are received
+// from the kernel when a sent message has the NLM_F_ACK flag set, indicating
+// that an Ack is requested.
+class ErrorAckMessage : public NetlinkMessage {
+ public:
+  static const uint16_t kMessageType;
+
+  ErrorAckMessage() : NetlinkMessage(kMessageType), error_(0) {}
+  virtual bool InitFromNlmsg(const nlmsghdr *const_msg);
+  virtual ByteString Encode(uint32_t sequence_number, uint16_t nlmsg_type);
+  virtual void Print(int log_level) const;
+  std::string ToString() const;
+  uint32_t error() const { return -error_; }
+
+ private:
+  uint32_t error_;
+
+  DISALLOW_COPY_AND_ASSIGN(ErrorAckMessage);
+};
+
+
+class NoopMessage : public NetlinkMessage {
+ public:
+  static const uint16_t kMessageType;
+
+  NoopMessage() : NetlinkMessage(kMessageType) {}
+  virtual ByteString Encode(uint32_t sequence_number, uint16_t nlmsg_type);
+  virtual void Print(int log_level) const;
+  std::string ToString() const { return "<NOOP>"; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NoopMessage);
+};
+
+
+class DoneMessage : public NetlinkMessage {
+ public:
+  static const uint16_t kMessageType;
+
+  DoneMessage() : NetlinkMessage(kMessageType) {}
+  virtual ByteString Encode(uint32_t sequence_number, uint16_t nlmsg_type);
+  virtual void Print(int log_level) const;
+  std::string ToString() const { return "<DONE with multipart message>"; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DoneMessage);
+};
+
+
+class OverrunMessage : public NetlinkMessage {
+ public:
+  static const uint16_t kMessageType;
+
+  OverrunMessage() : NetlinkMessage(kMessageType) {}
+  virtual ByteString Encode(uint32_t sequence_number, uint16_t nlmsg_type);
+  virtual void Print(int log_level) const;
+  std::string ToString() const { return "<OVERRUN - data lost>"; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(OverrunMessage);
+};
+
 // Objects of the |GenericNetlinkMessage| type represent messages that contain
 // a |genlmsghdr| after a |nlmsghdr|.  These messages seem to all contain a
 // payload that consists of a list of structured attributes (it's possible that
@@ -197,6 +264,40 @@
   DISALLOW_COPY_AND_ASSIGN(GenericNetlinkMessage);
 };
 
+// Control Messages
+
+class ControlNetlinkMessage : public GenericNetlinkMessage {
+ public:
+  static const uint16_t kMessageType;
+  ControlNetlinkMessage(uint8 command, const char *command_string)
+      : GenericNetlinkMessage(kMessageType, command, command_string) {}
+
+  virtual bool InitFromNlmsg(const nlmsghdr *msg);
+};
+
+class NewFamilyMessage : public ControlNetlinkMessage {
+ public:
+  static const uint8_t kCommand;
+  static const char kCommandString[];
+
+  NewFamilyMessage() : ControlNetlinkMessage(kCommand, kCommandString) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NewFamilyMessage);
+};
+
+class GetFamilyMessage : public ControlNetlinkMessage {
+ public:
+  static const uint8_t kCommand;
+  static const char kCommandString[];
+
+  GetFamilyMessage() : ControlNetlinkMessage(kCommand, kCommandString) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GetFamilyMessage);
+};
+
+
 // Class for messages received from the mac80211 drivers by way of the
 // cfg80211 kernel module.
 class Nl80211Message : public GenericNetlinkMessage {
@@ -289,17 +390,6 @@
 // Specific Nl80211Message types.
 //
 
-class AckMessage : public Nl80211Message {
- public:
-  static const uint8_t kCommand;
-  static const char kCommandString[];
-
-  AckMessage() : Nl80211Message(kCommand, kCommandString) {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AckMessage);
-};
-
 class AssociateMessage : public Nl80211Message {
  public:
   static const uint8_t kCommand;
@@ -397,21 +487,6 @@
 };
 
 
-class ErrorMessage : public Nl80211Message {
- public:
-  static const uint8_t kCommand;
-  static const char kCommandString[];
-
-  explicit ErrorMessage(uint32_t error);
-  virtual std::string ToString() const;
-
- private:
-  uint32_t error_;
-
-  DISALLOW_COPY_AND_ASSIGN(ErrorMessage);
-};
-
-
 class FrameTxStatusMessage : public Nl80211Message {
  public:
   static const uint8_t kCommand;
@@ -495,18 +570,6 @@
 };
 
 
-class NoopMessage : public Nl80211Message {
- public:
-  static const uint8_t kCommand;
-  static const char kCommandString[];
-
-  NoopMessage() : Nl80211Message(kCommand, kCommandString) {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NoopMessage);
-};
-
-
 class NotifyCqmMessage : public Nl80211Message {
  public:
   static const uint8_t kCommand;
@@ -591,6 +654,18 @@
 };
 
 
+class GetScanMessage : public Nl80211Message {
+ public:
+  static const uint8_t kCommand;
+  static const char kCommandString[];
+
+  GetScanMessage() : Nl80211Message(kCommand, kCommandString) {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GetScanMessage);
+};
+
+
 class TriggerScanMessage : public Nl80211Message {
  public:
   static const uint8_t kCommand;