1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2013 The Android Open Source Project 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License. 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 160ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1702e3dc3bc6e9fdb475bd13944f1c6764c921abbbPeter Qiu#ifndef SHILL_NET_GENERIC_NETLINK_MESSAGE_H_ 1802e3dc3bc6e9fdb475bd13944f1c6764c921abbbPeter Qiu#define SHILL_NET_GENERIC_NETLINK_MESSAGE_H_ 190ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 2002e3dc3bc6e9fdb475bd13944f1c6764c921abbbPeter Qiu#include "shill/net/attribute_list.h" 218d6b59704591ba9fad57751858835dc332dbdd37Peter Qiu#include "shill/net/byte_string.h" 2202e3dc3bc6e9fdb475bd13944f1c6764c921abbbPeter Qiu#include "shill/net/netlink_message.h" 231da9419d10a1a617cc634e79772335fa08b3420fPeter Qiu#include "shill/net/shill_export.h" 240ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 250ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrienamespace shill { 260ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 27b5b41b5ce5d06e9df1dbd7f319cc49ff982eb84ePaul Stewartclass NetlinkPacket; 28b5b41b5ce5d06e9df1dbd7f319cc49ff982eb84ePaul Stewart 290ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// Objects of the |GenericNetlinkMessage| type represent messages that contain 300ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// a |genlmsghdr| after a |nlmsghdr|. These messages seem to all contain a 310ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// payload that consists of a list of structured attributes (it's possible that 320ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// some messages might have a genlmsghdr and a different kind of payload but I 330ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// haven't seen one, yet). The genlmsghdr contains a command id that, when 340ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// combined with the family_id (from the nlmsghdr), describes the ultimate use 350ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// for the netlink message. 360ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// 370ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// An attribute contains a header and a chunk of data. The header contains an 380ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// id which is an enumerated value that describes the use of the attribute's 390ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// data (the datatype of the attribute's data is implied by the attribute id) 400ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// and the length of the header+data in bytes. The attribute id is, 410ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// confusingly, called the type (or nla_type -- this is _not_ the data type of 420ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// the attribute). Each family defines the meaning of the nla_types in the 430ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// context of messages in that family (for example, the nla_type with the 440ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// value 3 will always mean the same thing for attributes in the same family). 450ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// EXCEPTION: Some attributes are nested (that is, they contain a list of other 460ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// attributes rather than a single value). Each nested attribute defines the 470ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// meaning of the nla_types in the context of attributes that are nested under 480ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// this attribute (for example, the nla_type with the value 3 will have a 490ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// different meaning when nested under another attribute -- that meaning is 500ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// defined by the attribute under which it is nested). Fun. 510ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// 520ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// The GenericNetlink messages look like this: 530ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// 540ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// -----+-----+-+-------------------------------------------------+-+-- 550ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// ... | | | message payload | | 560ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// | | +------+-+----------------------------------------+ | 570ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// | nl | | | | attributes | | 580ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// | msg |p| genl |p+-----------+-+---------+-+--------+-----+p| ... 590ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// | hdr |a| msg |a| struct |p| attrib |p| struct | ... |a| 600ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// | |d| hdr |d| nlattr |a| payload |a| nlattr | |d| 610ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// | | | | | |d| |d| | | | 620ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// -----+-----+-+------+-+-----------+-+---------+-+--------+-----+-+-- 630ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// | ^ | | 640ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// |<-NLA_HDRLEN->| | | 6557282d5403b23162de1ded91ec8d73bdc19c922aPaul Stewart// |<-----hdr.nla_len----->| | 6657282d5403b23162de1ded91ec8d73bdc19c922aPaul Stewart// |<NLA_ALIGN(hdr.nla_len)->| 670ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 68ba24e6fd0f0f2b974e0e73039d7d92bb475f6857Peter Qiuclass SHILL_EXPORT GenericNetlinkMessage : public NetlinkMessage { 690ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie public: 707fab89734d88724a288e96a9996b15548c5294c7Ben Chan GenericNetlinkMessage(uint16_t my_message_type, uint8_t command, 71e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewart const char* command_string) 720ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie : NetlinkMessage(my_message_type), 730ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie attributes_(new AttributeList), 740ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie command_(command), 750ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie command_string_(command_string) {} 765ea763b83299b5fad76a87183fb39a74c2d3c61dBen Chan ~GenericNetlinkMessage() override {} 770ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 786acd966cabe0d75e0d9ae3f84c727c9b44a899b3Yunlian Jiang ByteString Encode(uint32_t sequence_number) override; 790ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 807fab89734d88724a288e96a9996b15548c5294c7Ben Chan uint8_t command() const { return command_; } 81e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewart const char* command_string() const { return command_string_; } 820ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie AttributeListConstRefPtr const_attributes() const { return attributes_; } 830ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie AttributeListRefPtr attributes() { return attributes_; } 840ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 856acd966cabe0d75e0d9ae3f84c727c9b44a899b3Yunlian Jiang void Print(int header_log_level, int detail_log_level) const override; 860ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 870ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie protected: 880ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie // Returns a string of bytes representing _both_ an |nlmsghdr| and a 890ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie // |genlmsghdr|, filled-in, and its padding. 906acd966cabe0d75e0d9ae3f84c727c9b44a899b3Yunlian Jiang ByteString EncodeHeader(uint32_t sequence_number) override; 91b5b41b5ce5d06e9df1dbd7f319cc49ff982eb84ePaul Stewart // Reads the |nlmsghdr| and |genlmsghdr| headers and consumes the latter 92b5b41b5ce5d06e9df1dbd7f319cc49ff982eb84ePaul Stewart // from the payload of |packet|. 93b5b41b5ce5d06e9df1dbd7f319cc49ff982eb84ePaul Stewart bool InitAndStripHeader(NetlinkPacket* packet) override; 940ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 950ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie AttributeListRefPtr attributes_; 967fab89734d88724a288e96a9996b15548c5294c7Ben Chan const uint8_t command_; 97e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewart const char* command_string_; 980ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 990ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie private: 1000ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie DISALLOW_COPY_AND_ASSIGN(GenericNetlinkMessage); 1010ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie}; 1020ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1030ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie// Control Messages 1040ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 105ba24e6fd0f0f2b974e0e73039d7d92bb475f6857Peter Qiuclass SHILL_EXPORT ControlNetlinkMessage : public GenericNetlinkMessage { 1060ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie public: 1070ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie static const uint16_t kMessageType; 108e67a78539a05ea7fc68ed5ca18f6d1de333a3086Paul Stewart ControlNetlinkMessage(uint8_t command, const char* command_string) 1090ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie : GenericNetlinkMessage(kMessageType, command, command_string) {} 1100ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1117347bf2b466ae8058e47b29aaf0583390405d866Wade Guthrie static uint16_t GetMessageType() { return kMessageType; } 1127347bf2b466ae8058e47b29aaf0583390405d866Wade Guthrie 113b5b41b5ce5d06e9df1dbd7f319cc49ff982eb84ePaul Stewart bool InitFromPacket(NetlinkPacket* packet, MessageContext context); 1140ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1150ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie // Message factory for all types of Control netlink message. 116b5b41b5ce5d06e9df1dbd7f319cc49ff982eb84ePaul Stewart static NetlinkMessage* CreateMessage(const NetlinkPacket& packet); 11740d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie 11840d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie private: 11940d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie DISALLOW_COPY_AND_ASSIGN(ControlNetlinkMessage); 1200ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie}; 1210ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 122ba24e6fd0f0f2b974e0e73039d7d92bb475f6857Peter Qiuclass SHILL_EXPORT NewFamilyMessage : public ControlNetlinkMessage { 1230ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie public: 1240ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie static const uint8_t kCommand; 1250ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie static const char kCommandString[]; 1260ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1270ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie NewFamilyMessage() : ControlNetlinkMessage(kCommand, kCommandString) {} 1280ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1290ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie private: 1300ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie DISALLOW_COPY_AND_ASSIGN(NewFamilyMessage); 1310ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie}; 1320ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 133ba24e6fd0f0f2b974e0e73039d7d92bb475f6857Peter Qiuclass SHILL_EXPORT GetFamilyMessage : public ControlNetlinkMessage { 1340ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie public: 1350ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie static const uint8_t kCommand; 1360ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie static const char kCommandString[]; 1370ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1382623f1a26f13538a3ab2f88fffac5767d99d4191Wade Guthrie GetFamilyMessage(); 1390ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 1400ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie private: 1410ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie DISALLOW_COPY_AND_ASSIGN(GetFamilyMessage); 1420ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie}; 1430ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 144ba24e6fd0f0f2b974e0e73039d7d92bb475f6857Peter Qiuclass SHILL_EXPORT UnknownControlMessage : public ControlNetlinkMessage { 14540d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie public: 14640d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie explicit UnknownControlMessage(uint8_t command) 14740d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie : ControlNetlinkMessage(command, "<UNKNOWN CONTROL MESSAGE>"), 14840d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie command_(command) {} 14940d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie 15040d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie private: 15140d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie uint8_t command_; 15240d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie DISALLOW_COPY_AND_ASSIGN(UnknownControlMessage); 15340d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie}; 15440d992cc0f7356f179b31ae71473538e0e09fd97Wade Guthrie 1550ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie} // namespace shill 1560ae4b8e23aeae86696bd021db3716fa2fbcadec9Wade Guthrie 15702e3dc3bc6e9fdb475bd13944f1c6764c921abbbPeter Qiu#endif // SHILL_NET_GENERIC_NETLINK_MESSAGE_H_ 158