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