blob: 7f3556c4485939770f1295d5786a755413768d0e [file] [log] [blame]
// 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 <vector>
#include <gtest/gtest.h>
#include "smbprovider/netbios_packet_parser.h"
#include "smbprovider/smbprovider_test_helper.h"
namespace smbprovider {
namespace {
constexpr int kNonFileServerNodeType = 0x00;
const std::vector<uint8_t> CreateName(const std::string& name) {
return std::vector<uint8_t>(name.begin(), name.end());
}
} // namespace
class NetBiosPacketParserTest : public testing::Test {
public:
NetBiosPacketParserTest() = default;
NetBiosPacketParserTest(const NetBiosPacketParserTest&) = delete;
NetBiosPacketParserTest& operator=(const NetBiosPacketParserTest&) = delete;
~NetBiosPacketParserTest() override = default;
protected:
const uint16_t transaction_id_ = 123;
};
// An empty packet returns no results.
TEST_F(NetBiosPacketParserTest, EmptyPacketReturnsNoResults) {
const std::vector<uint8_t> packet;
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_TRUE(results.empty());
}
// A well-formed packet with no hostnames returns no results.
TEST_F(NetBiosPacketParserTest, NoHostnamesReturnsNoResults) {
const std::vector<uint8_t> name = CreateName("testname");
const std::vector<std::vector<uint8_t>> hostnames;
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x20 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_TRUE(results.empty());
}
// A well-formed packet with one hostname parses successfully.
TEST_F(NetBiosPacketParserTest, OneHostnameSucceeds) {
const std::vector<uint8_t> name = CreateName("testname");
const std::string hostname_1 = "hostname1";
const std::vector<std::vector<uint8_t>> hostnames = {
CreateValidNetBiosHostname(hostname_1, netbios::kFileServerNodeType)};
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x20 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_EQ(1, results.size());
EXPECT_EQ(hostname_1, results[0]);
}
// A well-formed packet with two hostnames parses successfully.
TEST_F(NetBiosPacketParserTest, TwoHostnamesSucceeds) {
const std::vector<uint8_t> name = CreateName("testname");
const std::string hostname_1 = "hostname1";
const std::string hostname_2 = "hostname2";
const std::vector<std::vector<uint8_t>> hostnames = {
CreateValidNetBiosHostname(hostname_1, netbios::kFileServerNodeType),
CreateValidNetBiosHostname(hostname_2, netbios::kFileServerNodeType)};
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x20 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_EQ(2, results.size());
EXPECT_EQ(hostname_1, results[0]);
EXPECT_EQ(hostname_2, results[1]);
}
// The parser does not return non-FileServer hostnames.
TEST_F(NetBiosPacketParserTest, NonShareDoesntReturn) {
const std::vector<uint8_t> name = CreateName("testname");
const std::string hostname_1 = "hostname1";
const std::string hostname_2 = "hostname2";
const std::vector<std::vector<uint8_t>> hostnames = {
CreateValidNetBiosHostname(hostname_1, kNonFileServerNodeType),
CreateValidNetBiosHostname(hostname_2, netbios::kFileServerNodeType)};
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x20 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_EQ(1, results.size());
EXPECT_EQ(hostname_2, results[0]);
}
// A well-formed negative response returns no results.
TEST_F(NetBiosPacketParserTest, NegativeResponseFails) {
const std::vector<uint8_t> name = CreateName("testname");
const std::string hostname_1 = "hostname1";
const std::vector<std::vector<uint8_t>> hostnames = {
CreateValidNetBiosHostname(hostname_1, netbios::kFileServerNodeType)};
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x00 /* negative response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_TRUE(results.empty());
}
// A mal-formed packet with a name that is too long returns no results.
TEST_F(NetBiosPacketParserTest, NameTooLongFails) {
const std::vector<uint8_t> name = CreateName("testname");
const uint8_t name_length(150);
const std::string hostname_1 = "hostname1";
const std::vector<std::vector<uint8_t>> hostnames = {
CreateValidNetBiosHostname(hostname_1, netbios::kFileServerNodeType)};
const std::vector<uint8_t> packet =
CreateNetBiosResponsePacket(hostnames, name_length, name, transaction_id_,
0x20 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_TRUE(results.empty());
}
// A mal-formed packet with incorrectly formed hostnames returns no results.
TEST_F(NetBiosPacketParserTest, MalformedHostnamesFails) {
const std::vector<uint8_t> name = CreateName("testname");
const std::string bad_hostname = "tooooooolonggggghostnameeee";
const std::vector<std::vector<uint8_t>> hostnames = {
std::vector<uint8_t>(bad_hostname.begin(), bad_hostname.end())};
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x20 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_TRUE(results.empty());
}
// A well-formed packet with the transaction id that does not correspond to the
// broadcast returns no results.
TEST_F(NetBiosPacketParserTest, TestName) {
const std::vector<uint8_t> name = CreateName("testname");
const std::string hostname_1 = "hostname1";
const std::vector<std::vector<uint8_t>> hostnames = {
CreateValidNetBiosHostname(hostname_1, netbios::kFileServerNodeType)};
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x20 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_ + 1);
EXPECT_TRUE(results.empty());
}
// A positive response with the NBSTAT signal (0x21) instead of NB (0x20)
// returns a result correctly.
TEST_F(NetBiosPacketParserTest, AlternatePositiveResponseSucceeds) {
const std::vector<uint8_t> name = CreateName("testname");
const std::string hostname_1 = "hostname1";
const std::vector<std::vector<uint8_t>> hostnames = {
CreateValidNetBiosHostname(hostname_1, netbios::kFileServerNodeType)};
const std::vector<uint8_t> packet = CreateNetBiosResponsePacket(
hostnames, name, transaction_id_, 0x21 /* positive response */);
const std::vector<std::string> results =
netbios::ParsePacket(packet, transaction_id_);
EXPECT_EQ(1, results.size());
EXPECT_EQ(hostname_1, results[0]);
}
} // namespace smbprovider