Home | History | Annotate | Download | only in net
      1 //
      2 // Copyright (C) 2013 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef SHILL_NET_GENERIC_NETLINK_MESSAGE_H_
     18 #define SHILL_NET_GENERIC_NETLINK_MESSAGE_H_
     19 
     20 #include "shill/net/attribute_list.h"
     21 #include "shill/net/byte_string.h"
     22 #include "shill/net/netlink_message.h"
     23 #include "shill/net/shill_export.h"
     24 
     25 namespace shill {
     26 
     27 class NetlinkPacket;
     28 
     29 // Objects of the |GenericNetlinkMessage| type represent messages that contain
     30 // a |genlmsghdr| after a |nlmsghdr|.  These messages seem to all contain a
     31 // payload that consists of a list of structured attributes (it's possible that
     32 // some messages might have a genlmsghdr and a different kind of payload but I
     33 // haven't seen one, yet).  The genlmsghdr contains a command id that, when
     34 // combined with the family_id (from the nlmsghdr), describes the ultimate use
     35 // for the netlink message.
     36 //
     37 // An attribute contains a header and a chunk of data. The header contains an
     38 // id which is an enumerated value that describes the use of the attribute's
     39 // data (the datatype of the attribute's data is implied by the attribute id)
     40 // and the length of the header+data in bytes.  The attribute id is,
     41 // confusingly, called the type (or nla_type -- this is _not_ the data type of
     42 // the attribute).  Each family defines the meaning of the nla_types in the
     43 // context of messages in that family (for example, the nla_type with the
     44 // value 3 will always mean the same thing for attributes in the same family).
     45 // EXCEPTION: Some attributes are nested (that is, they contain a list of other
     46 // attributes rather than a single value).  Each nested attribute defines the
     47 // meaning of the nla_types in the context of attributes that are nested under
     48 // this attribute (for example, the nla_type with the value 3 will have a
     49 // different meaning when nested under another attribute -- that meaning is
     50 // defined by the attribute under which it is nested).  Fun.
     51 //
     52 // The GenericNetlink messages look like this:
     53 //
     54 // -----+-----+-+-------------------------------------------------+-+--
     55 //  ... |     | |              message payload                    | |
     56 //      |     | +------+-+----------------------------------------+ |
     57 //      | nl  | |      | |                attributes              | |
     58 //      | msg |p| genl |p+-----------+-+---------+-+--------+-----+p| ...
     59 //      | hdr |a| msg  |a|  struct   |p| attrib  |p| struct | ... |a|
     60 //      |     |d| hdr  |d|  nlattr   |a| payload |a| nlattr |     |d|
     61 //      |     | |      | |           |d|         |d|        |     | |
     62 // -----+-----+-+------+-+-----------+-+---------+-+--------+-----+-+--
     63 //                       |              ^        | |
     64 //                       |<-NLA_HDRLEN->|        | |
     65 //                       |<-----hdr.nla_len----->| |
     66 //                       |<NLA_ALIGN(hdr.nla_len)->|
     67 
     68 class SHILL_EXPORT GenericNetlinkMessage : public NetlinkMessage {
     69  public:
     70   GenericNetlinkMessage(uint16_t my_message_type, uint8_t command,
     71                         const char* command_string)
     72       : NetlinkMessage(my_message_type),
     73         attributes_(new AttributeList),
     74         command_(command),
     75         command_string_(command_string) {}
     76   ~GenericNetlinkMessage() override {}
     77 
     78   ByteString Encode(uint32_t sequence_number) override;
     79 
     80   uint8_t command() const { return command_; }
     81   const char* command_string() const { return command_string_; }
     82   AttributeListConstRefPtr const_attributes() const { return attributes_; }
     83   AttributeListRefPtr attributes() { return attributes_; }
     84 
     85   void Print(int header_log_level, int detail_log_level) const override;
     86 
     87  protected:
     88   // Returns a string of bytes representing _both_ an |nlmsghdr| and a
     89   // |genlmsghdr|, filled-in, and its padding.
     90   ByteString EncodeHeader(uint32_t sequence_number) override;
     91   // Reads the |nlmsghdr| and |genlmsghdr| headers and consumes the latter
     92   // from the payload of |packet|.
     93   bool InitAndStripHeader(NetlinkPacket* packet) override;
     94 
     95   AttributeListRefPtr attributes_;
     96   const uint8_t command_;
     97   const char* command_string_;
     98 
     99  private:
    100   DISALLOW_COPY_AND_ASSIGN(GenericNetlinkMessage);
    101 };
    102 
    103 // Control Messages
    104 
    105 class SHILL_EXPORT ControlNetlinkMessage : public GenericNetlinkMessage {
    106  public:
    107   static const uint16_t kMessageType;
    108   ControlNetlinkMessage(uint8_t command, const char* command_string)
    109       : GenericNetlinkMessage(kMessageType, command, command_string) {}
    110 
    111   static uint16_t GetMessageType() { return kMessageType; }
    112 
    113   bool InitFromPacket(NetlinkPacket* packet, MessageContext context);
    114 
    115   // Message factory for all types of Control netlink message.
    116   static NetlinkMessage* CreateMessage(const NetlinkPacket& packet);
    117 
    118  private:
    119   DISALLOW_COPY_AND_ASSIGN(ControlNetlinkMessage);
    120 };
    121 
    122 class SHILL_EXPORT NewFamilyMessage : public ControlNetlinkMessage {
    123  public:
    124   static const uint8_t kCommand;
    125   static const char kCommandString[];
    126 
    127   NewFamilyMessage() : ControlNetlinkMessage(kCommand, kCommandString) {}
    128 
    129  private:
    130   DISALLOW_COPY_AND_ASSIGN(NewFamilyMessage);
    131 };
    132 
    133 class SHILL_EXPORT GetFamilyMessage : public ControlNetlinkMessage {
    134  public:
    135   static const uint8_t kCommand;
    136   static const char kCommandString[];
    137 
    138   GetFamilyMessage();
    139 
    140  private:
    141   DISALLOW_COPY_AND_ASSIGN(GetFamilyMessage);
    142 };
    143 
    144 class SHILL_EXPORT UnknownControlMessage : public ControlNetlinkMessage {
    145  public:
    146   explicit UnknownControlMessage(uint8_t command)
    147       : ControlNetlinkMessage(command, "<UNKNOWN CONTROL MESSAGE>"),
    148         command_(command) {}
    149 
    150  private:
    151   uint8_t command_;
    152   DISALLOW_COPY_AND_ASSIGN(UnknownControlMessage);
    153 };
    154 
    155 }  // namespace shill
    156 
    157 #endif  // SHILL_NET_GENERIC_NETLINK_MESSAGE_H_
    158