1 // 2 // Copyright (C) 2015 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_NETLINK_PACKET_H_ 18 #define SHILL_NET_NETLINK_PACKET_H_ 19 20 #include <linux/genetlink.h> 21 #include <linux/netlink.h> 22 23 #include <memory> 24 25 #include <base/macros.h> 26 27 #include "shill/net/attribute_list.h" 28 #include "shill/net/shill_export.h" 29 30 namespace shill { 31 32 class ByteString; 33 34 class SHILL_EXPORT NetlinkPacket { 35 public: 36 NetlinkPacket(const unsigned char* buf, size_t len); 37 virtual ~NetlinkPacket(); 38 39 // Returns whether a packet was properly retrieved in the constructor. 40 bool IsValid() const; 41 42 // Returns the entire packet length (including the nlmsghdr). Callers 43 // can consder this to be the number of bytes consumed from |buf| in the 44 // constructor. This value will not change as data is consumed -- use 45 // GetRemainingLength() instead for this. 46 size_t GetLength() const; 47 48 // Get the message type from the header. 49 uint16_t GetMessageType() const; 50 51 // Get the sequence number from the header. 52 uint32_t GetMessageSequence() const; 53 54 // Returns the remaining (un-consumed) payload length. 55 size_t GetRemainingLength() const; 56 57 // Returns the payload data. It is a fatal error to call this method 58 // on an invalid packet. 59 const ByteString& GetPayload() const; 60 61 // Consume netlink attributes from the remaining payload. 62 bool ConsumeAttributes(const AttributeList::NewFromIdMethod& factory, 63 const AttributeListRefPtr& attributes); 64 65 // Consume |len| bytes out of the payload, and place them in |data|. 66 // Any trailing alignment padding in |payload| is also consumed. Returns 67 // true if there is enough data, otherwise returns false and does not 68 // modify |data|. 69 bool ConsumeData(size_t len, void* data); 70 71 // Copies the initial part of the payload to |header| without 72 // consuming any data. Returns true if this operation succeeds (there 73 // is enough data in the payload), false otherwise. 74 bool GetGenlMsgHdr(genlmsghdr* header) const; 75 76 // Returns the nlmsghdr associated with the packet. It is a fatal error 77 // to call this method on an invalid packet. 78 const nlmsghdr& GetNlMsgHeader() const; 79 80 protected: 81 // These getters are protected so that derived classes may allow 82 // the packet contents to be modified. 83 nlmsghdr* mutable_header() { return &header_; } 84 ByteString* mutable_payload() { return payload_.get(); } 85 void set_consumed_bytes(size_t consumed_bytes) { 86 consumed_bytes_ = consumed_bytes; 87 } 88 89 private: 90 friend class NetlinkPacketTest; 91 92 nlmsghdr header_; 93 std::unique_ptr<ByteString> payload_; 94 size_t consumed_bytes_; 95 96 DISALLOW_COPY_AND_ASSIGN(NetlinkPacket); 97 }; 98 99 // Mutable Netlink packets are used in unit tests where it is convenient 100 // to modify the header and payload of a packet before passing it to the 101 // NetlinkMessage subclasses or NetlinkManager. 102 class SHILL_EXPORT MutableNetlinkPacket : public NetlinkPacket { 103 public: 104 MutableNetlinkPacket(const unsigned char* buf, size_t len); 105 virtual ~MutableNetlinkPacket(); 106 107 // Reset consumed_bytes_ as if this packet never underwent processing. 108 // This is useful for unit tests that wish to re-send a previously 109 // processed packet. 110 void ResetConsumedBytes(); 111 112 // Returns mutable references to the header and payload. 113 nlmsghdr* GetMutableHeader(); 114 ByteString* GetMutablePayload(); 115 116 // Set the message type in the header. 117 void SetMessageType(uint16_t type); 118 119 // Set the sequence number in the header. 120 void SetMessageSequence(uint32_t sequence); 121 122 private: 123 DISALLOW_COPY_AND_ASSIGN(MutableNetlinkPacket); 124 }; 125 126 } // namespace shill 127 128 #endif // SHILL_NET_NETLINK_PACKET_H_ 129