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 25namespace shill { 26 27class 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 68class 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 105class 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 122class 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 133class 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 144class 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