Commit 4e51fbfd authored by Bailey Berro's avatar Bailey Berro Committed by Commit Bot

Create NetBiosHostLocator

This change creates the NetBiosHostLocator class and implements the
networking related helper functions.

NetBiosHostLocator:
- Performs a NetBios Name Request Query via a NetBiosClient
- Sends response packets to the CrOS Smbprovider daemon to be parsed
- Collects and returns responses to the caller as <hostname, ip> pairs

Bug: 757625
Change-Id: I7bd6c93c620e05b1c4d945c8a9f289d08fdcb788
Reviewed-on: https://chromium-review.googlesource.com/1019862
Commit-Queue: Bailey Berro <baileyberro@chromium.org>
Reviewed-by: default avatarZentaro Kavanagh <zentaro@chromium.org>
Cr-Commit-Position: refs/heads/master@{#566034}
parent 567dfecc
......@@ -1598,6 +1598,8 @@ source_set("chromeos") {
"smb_client/discovery/netbios_client.cc",
"smb_client/discovery/netbios_client.h",
"smb_client/discovery/netbios_client_interface.h",
"smb_client/discovery/netbios_host_locator.cc",
"smb_client/discovery/netbios_host_locator.h",
"smb_client/discovery/network_scanner.cc",
"smb_client/discovery/network_scanner.h",
"smb_client/smb_constants.cc",
......@@ -2130,6 +2132,7 @@ source_set("unit_tests") {
"settings/stub_cros_settings_provider_unittest.cc",
"smb_client/discovery/in_memory_host_locator_unittest.cc",
"smb_client/discovery/mdns_host_locator_unittest.cc",
"smb_client/discovery/netbios_host_locator_unittest.cc",
"smb_client/discovery/network_scanner_unittest.cc",
"smb_client/smb_errors_unittest.cc",
"smb_client/smb_file_system_id_test.cc",
......
// Copyright 2018 The Chromium 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 "chrome/browser/chromeos/smb_client/discovery/netbios_host_locator.h"
#include "net/base/network_change_notifier.h"
namespace chromeos {
namespace smb_client {
net::IPAddress CalculateBroadcastAddress(
const net::NetworkInterface& interface) {
net::IPAddress internet_address = interface.address;
const uint32_t inverted_net_mask = 0xffffffff >> interface.prefix_length;
net::IPAddressBytes bytes = internet_address.bytes();
uint8_t b0 = bytes[0] | (inverted_net_mask >> 24);
uint8_t b1 = bytes[1] | (inverted_net_mask >> 16);
uint8_t b2 = bytes[2] | (inverted_net_mask >> 8);
uint8_t b3 = bytes[3] | (inverted_net_mask);
net::IPAddress broadcast_address(b0, b1, b2, b3);
return broadcast_address;
}
bool ShouldUseInterface(const net::NetworkInterface& interface) {
return interface.address.IsIPv4() &&
(interface.type == net::NetworkChangeNotifier::CONNECTION_ETHERNET ||
interface.type == net::NetworkChangeNotifier::CONNECTION_WIFI);
}
NetBiosHostLocator::NetBiosHostLocator(GetInterfacesFunction get_interfaces)
: get_interfaces_(std::move(get_interfaces)) {}
NetBiosHostLocator::~NetBiosHostLocator() = default;
void NetBiosHostLocator::FindHosts(FindHostsCallback callback) {
DCHECK(callback);
callback_ = std::move(callback);
}
net::NetworkInterfaceList NetBiosHostLocator::GetNetworkInterfaceList() {
return get_interfaces_.Run();
}
} // namespace smb_client
} // namespace chromeos
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_SMB_CLIENT_DISCOVERY_NETBIOS_HOST_LOCATOR_H_
#define CHROME_BROWSER_CHROMEOS_SMB_CLIENT_DISCOVERY_NETBIOS_HOST_LOCATOR_H_
#include <string>
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/smb_client/discovery/host_locator.h"
#include "net/base/network_interfaces.h"
namespace chromeos {
namespace smb_client {
// Calculates the broadcast address of a network interface.
net::IPAddress CalculateBroadcastAddress(
const net::NetworkInterface& interface);
// Returns true if a network interface should be used for NetBios discovery.
bool ShouldUseInterface(const net::NetworkInterface& interface);
// HostLocator implementation that uses NetBIOS to locate hosts.
class NetBiosHostLocator : public HostLocator,
public base::SupportsWeakPtr<NetBiosHostLocator> {
public:
using GetInterfacesFunction =
base::RepeatingCallback<net::NetworkInterfaceList()>;
explicit NetBiosHostLocator(GetInterfacesFunction get_interfaces);
~NetBiosHostLocator() override;
// HostLocator override.
void FindHosts(FindHostsCallback callback) override;
private:
// Returns a list of network interfaces on the device.
net::NetworkInterfaceList GetNetworkInterfaceList();
GetInterfacesFunction get_interfaces_;
FindHostsCallback callback_;
HostMap results_;
DISALLOW_COPY_AND_ASSIGN(NetBiosHostLocator);
};
} // namespace smb_client
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SMB_CLIENT_DISCOVERY_NETBIOS_HOST_LOCATOR_H_
// Copyright 2018 The Chromium 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 "chrome/browser/chromeos/smb_client/discovery/netbios_host_locator.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace smb_client {
namespace {
// Helper method to create a NetworkInterface for testing.
net::NetworkInterface CreateNetworkInterface(
const net::IPAddress& address,
uint32_t prefix_length,
net::NetworkChangeNotifier::ConnectionType type) {
net::NetworkInterface interface;
interface.address = address;
interface.prefix_length = prefix_length;
interface.type = type;
return interface;
}
} // namespace
class NetBiosHostLocatorTest : public testing::Test {
public:
NetBiosHostLocatorTest() = default;
~NetBiosHostLocatorTest() override = default;
private:
DISALLOW_COPY_AND_ASSIGN(NetBiosHostLocatorTest);
};
// Calculate broadcast address correctly calculates the broadcast address
// of a NetworkInterface.
TEST_F(NetBiosHostLocatorTest, CalculateBroadcastAddress) {
const net::NetworkInterface interface = CreateNetworkInterface(
net::IPAddress(192, 168, 50, 152), 24 /* prefix_length */,
net::NetworkChangeNotifier::CONNECTION_WIFI);
EXPECT_EQ(net::IPAddress(192, 168, 50, 255),
CalculateBroadcastAddress(interface));
}
// ShouldUseInterface returns true for Wifi and Ethernet interfaces but false
// for other types of interfaces.
TEST_F(NetBiosHostLocatorTest, ShouldUseWifiAndEthernetInterfaces) {
const net::NetworkInterface interface_wifi = CreateNetworkInterface(
net::IPAddress::IPv4Localhost(), 24 /* prefix_length */,
net::NetworkChangeNotifier::CONNECTION_WIFI);
const net::NetworkInterface interface_ethernet = CreateNetworkInterface(
net::IPAddress::IPv4Localhost(), 24 /* prefix_length */,
net::NetworkChangeNotifier::CONNECTION_WIFI);
const net::NetworkInterface interface_bluetooth = CreateNetworkInterface(
net::IPAddress::IPv4Localhost(), 24 /* prefix_length */,
net::NetworkChangeNotifier::CONNECTION_BLUETOOTH);
EXPECT_TRUE(ShouldUseInterface(interface_wifi));
EXPECT_TRUE(ShouldUseInterface(interface_ethernet));
EXPECT_FALSE(ShouldUseInterface(interface_bluetooth));
}
// ShouldUseInterface returns true for IPv4 interfaces but false for IPv6
// interfaces
TEST_F(NetBiosHostLocatorTest, OnlyProcessIPv4Interfaces) {
const net::NetworkInterface interface_ipv4 = CreateNetworkInterface(
net::IPAddress::IPv4Localhost(), 24 /* prefix_length */,
net::NetworkChangeNotifier::CONNECTION_WIFI);
const net::NetworkInterface interface_ipv6 = CreateNetworkInterface(
net::IPAddress::IPv6Localhost(), 24 /* prefix_length */,
net::NetworkChangeNotifier::CONNECTION_WIFI);
EXPECT_TRUE(ShouldUseInterface(interface_ipv4));
EXPECT_FALSE(ShouldUseInterface(interface_ipv6));
}
} // namespace smb_client
} // namespace chromeos
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment