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: GenericNetlinkMessage(uint16_t my_message_type,uint8_t command,const char * command_string)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) {} ~GenericNetlinkMessage()76 ~GenericNetlinkMessage() override {} 77 78 ByteString Encode(uint32_t sequence_number) override; 79 command()80 uint8_t command() const { return command_; } command_string()81 const char* command_string() const { return command_string_; } const_attributes()82 AttributeListConstRefPtr const_attributes() const { return attributes_; } 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; ControlNetlinkMessage(uint8_t command,const char * command_string)108 ControlNetlinkMessage(uint8_t command, const char* command_string) 109 : GenericNetlinkMessage(kMessageType, command, command_string) {} 110 GetMessageType()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 NewFamilyMessage()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: UnknownControlMessage(uint8_t command)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