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.
mutable_header()83   nlmsghdr* mutable_header() { return &header_; }
mutable_payload()84   ByteString* mutable_payload() { return payload_.get(); }
set_consumed_bytes(size_t consumed_bytes)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