// 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 "smbprovider/netbios_packet_parser.h"

#include <utility>

#include <base/logging.h>
#include <base/strings/string_util.h>

namespace smbprovider {
namespace netbios {
namespace {

// https://tools.ietf.org/html/rfc1002
// Section 4.2.13
constexpr int kMinimumValidPacketSize = 26;
constexpr int kNBNSResourceRecord = 0x20;
constexpr int kNBNSSTATUSResourceRecord = 0x21;
// Packet Offsets
constexpr int kEntriesOffset = 25;
constexpr int kEntryCountOffset = 24;
constexpr int kNameLengthOffset = 12;
constexpr int kPositiveResponseOffset = 14;

// Checks whether a NetBios Name Response packet corresponds to the
// transaction.
bool HasValidTransactionId(const std::vector<uint8_t>& packet,
                           uint16_t expected_transaction_id) {
  DCHECK_GE(packet.size(), 2);

  const uint16_t actual_transaction_id = (packet[0] << 8) | packet[1];

  return actual_transaction_id == expected_transaction_id;
}

// Checks whether a NetBios Name Response packet is a positive response.
bool IsPositiveNameResponse(const std::vector<uint8_t>& packet,
                            uint32_t byte_index) {
  DCHECK_GT(packet.size(), byte_index + 1);

  const uint16_t node_status =
      (packet[byte_index] << 8) | packet[byte_index + 1];

  return node_status == kNBNSResourceRecord ||
         node_status == kNBNSSTATUSResourceRecord;
}

size_t GetExpectedPacketLength(uint8_t name_length, uint8_t entry_count) {
  return kEntriesOffset + name_length + entry_count * kServerEntrySize;
}

}  // namespace

std::vector<std::string> ParsePacket(const std::vector<uint8_t>& packet,
                                     uint16_t transaction_id) {
  if (packet.size() < kMinimumValidPacketSize) {
    return std::vector<std::string>();
  }

  // Check the transaction id.
  if (!HasValidTransactionId(packet, transaction_id)) {
    // This response is not to our broadcast.
    return std::vector<std::string>();
  }

  // Get name length.
  const uint8_t name_length = packet[kNameLengthOffset];

  // Check if it's a Positive response.
  if (kPositiveResponseOffset + name_length + 1 >= packet.size()) {
    return std::vector<std::string>();
  }
  if (!IsPositiveNameResponse(packet, kPositiveResponseOffset + name_length)) {
    // Negative response to the broadcast.
    return std::vector<std::string>();
  }

  // Get Address List entry count.
  if (kEntryCountOffset + name_length >= packet.size()) {
    return std::vector<std::string>();
  }
  const uint8_t entry_count = packet[kEntryCountOffset + name_length];

  // Check that there are the correct number of bytes remaining in the packet.
  if (GetExpectedPacketLength(name_length, entry_count) > packet.size()) {
    return std::vector<std::string>();
  }

  // Get Servers.
  uint32_t byte_index = kEntriesOffset + name_length;
  std::vector<std::string> servers;
  for (int i = 0; i < entry_count; ++i) {
    DCHECK_LE(byte_index + kServerEntrySize, packet.size());

    // Get Server name.
    std::string server(packet.begin() + byte_index,
                       packet.begin() + byte_index + kServerNameLength);
    byte_index += kServerNameLength;

    // Get type.
    const uint8_t type = packet[byte_index];
    byte_index += 1;
    if (type == kFileServerNodeType) {
      base::TrimWhitespaceASCII(server, base::TRIM_TRAILING, &server);
      servers.push_back(std::move(server));
    }

    // Skip flags.
    byte_index += 2;
  }

  return servers;
}

}  // namespace netbios
}  // namespace smbprovider
