blob: d881ce3dd3bc705a8a9039cf99ed3c75325193d0 [file] [log] [blame] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shill/net/ipv4_address.h"
#include <arpa/inet.h>
#include <array>
#include <base/logging.h>
#include <gtest/gtest.h>
namespace shill {
namespace {
TEST(IPv4AddressTest, DefaultConstructor) {
const IPv4Address default_addr;
IPv4Address::DataType data{0, 0, 0, 0};
EXPECT_EQ(default_addr.data(), data);
EXPECT_EQ(default_addr, IPv4Address(0, 0, 0, 0));
}
TEST(IPv4AddressTest, Constructor) {
const std::array<uint8_t, 4> data{192, 168, 10, 1};
// Constructed from raw number.
const IPv4Address address1(192, 168, 10, 1);
// Constructed from std::array.
const IPv4Address address2(data);
// Constructed from other instance.
const IPv4Address address3(address1);
EXPECT_EQ(address1.data(), data);
EXPECT_EQ(address1, address2);
EXPECT_EQ(address1, address3);
}
TEST(IPv4AddressTest, CreateFromString_Success) {
const auto address = IPv4Address::CreateFromString("192.168.10.1");
ASSERT_TRUE(address);
EXPECT_EQ(*address, IPv4Address(192, 168, 10, 1));
}
TEST(IPv4AddressTest, ToString) {
const IPv4Address address(192, 168, 10, 1);
EXPECT_EQ(address.ToString(), "192.168.10.1");
// Make sure std::ostream operator<<() works.
LOG(INFO) << "address = " << address;
}
TEST(IPv4AddressTest, CreateFromString_Fail) {
EXPECT_FALSE(IPv4Address::CreateFromString(""));
EXPECT_FALSE(IPv4Address::CreateFromString("192.168.10.1/24"));
EXPECT_FALSE(IPv4Address::CreateFromString("fe80::1aa9:5ff:7ebf:14c5"));
}
TEST(IPv4AddressTest, ToByteString) {
const std::string expected{
static_cast<char>(192),
static_cast<char>(168),
static_cast<char>(10),
static_cast<char>(1),
};
const IPv4Address address(192, 168, 10, 1);
EXPECT_EQ(address.ToByteString(), expected);
}
TEST(IPv4AddressTest, CreateFromBytes) {
const auto expected = IPv4Address(192, 168, 10, 1);
const uint8_t bytes[4] = {192, 168, 10, 1};
EXPECT_EQ(*IPv4Address::CreateFromBytes(bytes, std::size(bytes)), expected);
const std::string byte_string = {static_cast<char>(192),
static_cast<char>(168),
static_cast<char>(10), static_cast<char>(1)};
EXPECT_EQ(
*IPv4Address::CreateFromBytes(byte_string.c_str(), byte_string.size()),
expected);
}
TEST(IPv4AddressTest, IsZero) {
const IPv4Address default_addr;
EXPECT_TRUE(default_addr.IsZero());
const IPv4Address address(0, 0, 0, 1);
EXPECT_FALSE(address.IsZero());
}
TEST(IPv4AddressTest, Order) {
const IPv4Address kOrderedAddresses[] = {
{127, 0, 0, 1}, {192, 168, 1, 1}, {192, 168, 1, 32},
{192, 168, 2, 1}, {192, 168, 2, 32}, {255, 255, 255, 255}};
for (size_t i = 0; i < std::size(kOrderedAddresses); ++i) {
for (size_t j = 0; j < std::size(kOrderedAddresses); ++j) {
if (i < j) {
EXPECT_TRUE(kOrderedAddresses[i] < kOrderedAddresses[j]);
} else {
EXPECT_FALSE(kOrderedAddresses[i] < kOrderedAddresses[j]);
}
}
}
}
TEST(IPv4CIDR, CreateFromCIDRString) {
const auto cidr1 = IPv4CIDR::CreateFromCIDRString("192.168.10.1/0");
ASSERT_TRUE(cidr1);
EXPECT_EQ(cidr1->address(), IPv4Address(192, 168, 10, 1));
EXPECT_EQ(cidr1->prefix_length(), 0);
const auto cidr2 = IPv4CIDR::CreateFromCIDRString("192.168.10.1/25");
ASSERT_TRUE(cidr2);
EXPECT_EQ(cidr2->address(), IPv4Address(192, 168, 10, 1));
EXPECT_EQ(cidr2->prefix_length(), 25);
const auto cidr3 = IPv4CIDR::CreateFromCIDRString("192.168.10.1/32");
ASSERT_TRUE(cidr3);
EXPECT_EQ(cidr3->address(), IPv4Address(192, 168, 10, 1));
EXPECT_EQ(cidr3->prefix_length(), 32);
}
TEST(IPv4CIDR, CreateFromCIDRString_Fail) {
EXPECT_FALSE(IPv4CIDR::CreateFromCIDRString("192.168.10.1"));
EXPECT_FALSE(IPv4CIDR::CreateFromCIDRString("192.168.10.1/-1"));
EXPECT_FALSE(IPv4CIDR::CreateFromCIDRString("192.168.10.1/33"));
EXPECT_FALSE(IPv4CIDR::CreateFromCIDRString("192.168.10/24"));
EXPECT_FALSE(IPv4CIDR::CreateFromCIDRString("::1"));
EXPECT_FALSE(IPv4CIDR::CreateFromCIDRString("::1/24"));
}
TEST(IPv4CIDR, CreateFromStringAndPrefix) {
const auto cidr1 = IPv4CIDR::CreateFromStringAndPrefix("192.168.10.1", 0);
ASSERT_TRUE(cidr1);
EXPECT_EQ(cidr1->address(), IPv4Address(192, 168, 10, 1));
EXPECT_EQ(cidr1->prefix_length(), 0);
const auto cidr2 = IPv4CIDR::CreateFromStringAndPrefix("192.168.10.1", 25);
ASSERT_TRUE(cidr2);
EXPECT_EQ(cidr2->address(), IPv4Address(192, 168, 10, 1));
EXPECT_EQ(cidr2->prefix_length(), 25);
const auto cidr3 = IPv4CIDR::CreateFromStringAndPrefix("192.168.10.1", 32);
ASSERT_TRUE(cidr3);
EXPECT_EQ(cidr3->address(), IPv4Address(192, 168, 10, 1));
EXPECT_EQ(cidr3->prefix_length(), 32);
}
TEST(IPv4CIDR, CreateFromAddressAndPrefix) {
const IPv4Address address(192, 168, 10, 1);
ASSERT_TRUE(IPv4CIDR::CreateFromAddressAndPrefix(address, 0));
ASSERT_TRUE(IPv4CIDR::CreateFromAddressAndPrefix(address, 25));
ASSERT_TRUE(IPv4CIDR::CreateFromAddressAndPrefix(address, 32));
ASSERT_FALSE(IPv4CIDR::CreateFromAddressAndPrefix(address, 33));
ASSERT_FALSE(IPv4CIDR::CreateFromAddressAndPrefix(address, -1));
}
TEST(IPv4CIDR, DefaultConstructor) {
const IPv4CIDR default_cidr;
EXPECT_EQ(default_cidr.address(), IPv4Address());
EXPECT_EQ(default_cidr.prefix_length(), 0);
const IPv4Address address(192, 168, 10, 1);
const auto cidr = IPv4CIDR(address);
EXPECT_EQ(cidr.address(), address);
EXPECT_EQ(cidr.prefix_length(), 0);
}
TEST(IPv4CIDR, GetPrefixAddress) {
const auto cidr1 = *IPv4CIDR::CreateFromCIDRString("192.168.10.123/24");
EXPECT_EQ(cidr1.GetPrefixAddress().ToString(), "192.168.10.0");
const auto cidr2 = *IPv4CIDR::CreateFromCIDRString("192.168.255.123/20");
EXPECT_EQ(cidr2.GetPrefixAddress().ToString(), "192.168.240.0");
}
TEST(IPv4CIDR, GetBroadcast) {
const auto cidr1 = *IPv4CIDR::CreateFromCIDRString("192.168.10.123/24");
EXPECT_EQ(cidr1.GetBroadcast().ToString(), "192.168.10.255");
const auto cidr2 = *IPv4CIDR::CreateFromCIDRString("192.168.1.123/20");
EXPECT_EQ(cidr2.GetBroadcast().ToString(), "192.168.15.255");
}
TEST(IPv4CIDR, InSameSubnetWith) {
const auto cidr = *IPv4CIDR::CreateFromCIDRString("192.168.10.123/24");
EXPECT_TRUE(cidr.InSameSubnetWith(IPv4Address(192, 168, 10, 1)));
EXPECT_TRUE(cidr.InSameSubnetWith(IPv4Address(192, 168, 10, 123)));
EXPECT_TRUE(cidr.InSameSubnetWith(IPv4Address(192, 168, 10, 255)));
EXPECT_FALSE(cidr.InSameSubnetWith(IPv4Address(192, 168, 11, 123)));
EXPECT_FALSE(cidr.InSameSubnetWith(IPv4Address(193, 168, 10, 123)));
}
TEST(IPv4CIDR, ToString) {
const std::string cidr_string = "192.168.10.123/24";
const auto cidr = *IPv4CIDR::CreateFromCIDRString(cidr_string);
EXPECT_EQ(cidr.ToString(), cidr_string);
// Make sure std::ostream operator<<() works.
LOG(INFO) << "cidr = " << cidr;
}
TEST(IPv4CIDR, GetNetmask) {
EXPECT_EQ(*IPv4CIDR::GetNetmask(0), IPv4Address(0, 0, 0, 0));
EXPECT_EQ(*IPv4CIDR::GetNetmask(1), IPv4Address(128, 0, 0, 0));
EXPECT_EQ(*IPv4CIDR::GetNetmask(4), IPv4Address(240, 0, 0, 0));
EXPECT_EQ(*IPv4CIDR::GetNetmask(8), IPv4Address(255, 0, 0, 0));
EXPECT_EQ(*IPv4CIDR::GetNetmask(16), IPv4Address(255, 255, 0, 0));
EXPECT_EQ(*IPv4CIDR::GetNetmask(24), IPv4Address(255, 255, 255, 0));
EXPECT_EQ(*IPv4CIDR::GetNetmask(31), IPv4Address(255, 255, 255, 254));
EXPECT_EQ(*IPv4CIDR::GetNetmask(32), IPv4Address(255, 255, 255, 255));
EXPECT_FALSE(IPv4CIDR::GetNetmask(-1));
EXPECT_FALSE(IPv4CIDR::GetNetmask(33));
}
TEST(IPv4CIDR, ToNetmask) {
const auto cidr1 = *IPv4CIDR::CreateFromCIDRString("192.168.2.1/0");
EXPECT_EQ(cidr1.ToNetmask(), IPv4Address(0, 0, 0, 0));
const auto cidr2 = *IPv4CIDR::CreateFromCIDRString("192.168.2.1/8");
EXPECT_EQ(cidr2.ToNetmask(), IPv4Address(255, 0, 0, 0));
const auto cidr3 = *IPv4CIDR::CreateFromCIDRString("192.168.2.1/24");
EXPECT_EQ(cidr3.ToNetmask(), IPv4Address(255, 255, 255, 0));
const auto cidr4 = *IPv4CIDR::CreateFromCIDRString("192.168.2.1/32");
EXPECT_EQ(cidr4.ToNetmask(), IPv4Address(255, 255, 255, 255));
}
} // namespace
} // namespace shill