C++程序  |  129行  |  4.11 KB

//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#ifndef SHILL_NET_NETLINK_PACKET_H_
#define SHILL_NET_NETLINK_PACKET_H_

#include <linux/genetlink.h>
#include <linux/netlink.h>

#include <memory>

#include <base/macros.h>

#include "shill/net/attribute_list.h"
#include "shill/net/shill_export.h"

namespace shill {

class ByteString;

class SHILL_EXPORT NetlinkPacket {
 public:
  NetlinkPacket(const unsigned char* buf, size_t len);
  virtual ~NetlinkPacket();

  // Returns whether a packet was properly retrieved in the constructor.
  bool IsValid() const;

  // Returns the entire packet length (including the nlmsghdr).  Callers
  // can consder this to be the number of bytes consumed from |buf| in the
  // constructor.  This value will not change as data is consumed -- use
  // GetRemainingLength() instead for this.
  size_t GetLength() const;

  // Get the message type from the header.
  uint16_t GetMessageType() const;

  // Get the sequence number from the header.
  uint32_t GetMessageSequence() const;

  // Returns the remaining (un-consumed) payload length.
  size_t GetRemainingLength() const;

  // Returns the payload data.  It is a fatal error to call this method
  // on an invalid packet.
  const ByteString& GetPayload() const;

  // Consume netlink attributes from the remaining payload.
  bool ConsumeAttributes(const AttributeList::NewFromIdMethod& factory,
                         const AttributeListRefPtr& attributes);

  // Consume |len| bytes out of the payload, and place them in |data|.
  // Any trailing alignment padding in |payload| is also consumed.  Returns
  // true if there is enough data, otherwise returns false and does not
  // modify |data|.
  bool ConsumeData(size_t len, void* data);

  // Copies the initial part of the payload to |header| without
  // consuming any data.  Returns true if this operation succeeds (there
  // is enough data in the payload), false otherwise.
  bool GetGenlMsgHdr(genlmsghdr* header) const;

  // Returns the nlmsghdr associated with the packet.  It is a fatal error
  // to call this method on an invalid packet.
  const nlmsghdr& GetNlMsgHeader() const;

 protected:
  // These getters are protected so that derived classes may allow
  // the packet contents to be modified.
  nlmsghdr* mutable_header() { return &header_; }
  ByteString* mutable_payload() { return payload_.get(); }
  void set_consumed_bytes(size_t consumed_bytes) {
      consumed_bytes_ = consumed_bytes;
  }

 private:
  friend class NetlinkPacketTest;

  nlmsghdr header_;
  std::unique_ptr<ByteString> payload_;
  size_t consumed_bytes_;

  DISALLOW_COPY_AND_ASSIGN(NetlinkPacket);
};

// Mutable Netlink packets are used in unit tests where it is convenient
// to modify the header and payload of a packet before passing it to the
// NetlinkMessage subclasses or NetlinkManager.
class SHILL_EXPORT MutableNetlinkPacket : public NetlinkPacket {
 public:
  MutableNetlinkPacket(const unsigned char* buf, size_t len);
  virtual ~MutableNetlinkPacket();

  // Reset consumed_bytes_ as if this packet never underwent processing.
  // This is useful for unit tests that wish to re-send a previously
  // processed packet.
  void ResetConsumedBytes();

  // Returns mutable references to the header and payload.
  nlmsghdr* GetMutableHeader();
  ByteString* GetMutablePayload();

  // Set the message type in the header.
  void SetMessageType(uint16_t type);

  // Set the sequence number in the header.
  void SetMessageSequence(uint32_t sequence);

 private:
  DISALLOW_COPY_AND_ASSIGN(MutableNetlinkPacket);
};

}  // namespace shill

#endif  // SHILL_NET_NETLINK_PACKET_H_