Home | History | Annotate | Download | only in net
      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