// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/net/netlink_packet.h"

#include <algorithm>

#include <base/logging.h>

#include "shill/net/byte_string.h"

namespace shill {

NetlinkPacket::NetlinkPacket(const unsigned char* buf, size_t len)
    : consumed_bytes_(0) {
  if (!buf || len < sizeof(header_)) {
    LOG(ERROR) << "Cannot retrieve header.";
    return;
  }

  memcpy(&header_, buf, sizeof(header_));
  if (len < header_.nlmsg_len || header_.nlmsg_len < sizeof(header_)) {
    LOG(ERROR) << "Discarding incomplete / invalid message.";
    return;
  }

  payload_.reset(new ByteString(buf + sizeof(header_), len - sizeof(header_)));
}

NetlinkPacket::~NetlinkPacket() {}

bool NetlinkPacket::IsValid() const {
  return payload_ != nullptr;
}

size_t NetlinkPacket::GetLength() const {
  return GetNlMsgHeader().nlmsg_len;
}

uint16_t NetlinkPacket::GetMessageType() const {
  return GetNlMsgHeader().nlmsg_type;
}

uint32_t NetlinkPacket::GetMessageSequence() const {
  return GetNlMsgHeader().nlmsg_seq;
}

size_t NetlinkPacket::GetRemainingLength() const {
  return GetPayload().GetLength() - consumed_bytes_;
}

const ByteString& NetlinkPacket::GetPayload() const {
  CHECK(IsValid());
  return *payload_;
}

bool NetlinkPacket::ConsumeAttributes(
    const AttributeList::NewFromIdMethod& factory,
    const AttributeListRefPtr& attributes) {
  bool result = attributes->Decode(GetPayload(), consumed_bytes_, factory);
  consumed_bytes_ = GetPayload().GetLength();
  return result;
}

bool NetlinkPacket::ConsumeData(size_t len, void* data) {
  if (GetRemainingLength() < len) {
    LOG(ERROR) << "Not enough bytes remaining.";
    return false;
  }

  memcpy(data, payload_->GetData() + consumed_bytes_, len);
  consumed_bytes_ =
      std::min(payload_->GetLength(), consumed_bytes_ + NLMSG_ALIGN(len));
  return true;
}

const nlmsghdr& NetlinkPacket::GetNlMsgHeader() const {
  CHECK(IsValid());
  return header_;
}

bool NetlinkPacket::GetGenlMsgHdr(genlmsghdr* header) const {
  if (GetPayload().GetLength() < sizeof(*header)) {
    return false;
  }
  memcpy(header, payload_->GetConstData(), sizeof(*header));
  return true;
}

MutableNetlinkPacket::MutableNetlinkPacket(const unsigned char* buf, size_t len)
    : NetlinkPacket(buf, len) {}

MutableNetlinkPacket::~MutableNetlinkPacket() {}

void MutableNetlinkPacket::ResetConsumedBytes() {
  set_consumed_bytes(0);
}

nlmsghdr* MutableNetlinkPacket::GetMutableHeader() {
  CHECK(IsValid());
  return mutable_header();
}

ByteString* MutableNetlinkPacket::GetMutablePayload() {
  CHECK(IsValid());
  return mutable_payload();
}

void MutableNetlinkPacket::SetMessageType(uint16_t type) {
  mutable_header()->nlmsg_type = type;
}

void MutableNetlinkPacket::SetMessageSequence(uint32_t sequence) {
  mutable_header()->nlmsg_seq = sequence;
}

}  // namespace shill.
