mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-03-18 19:32:41 +00:00
Network: Improve IPv4PortRange::ToString to support CIDR notation and only last octet difference.
This commit is contained in:
parent
0ff8fb71a3
commit
cbd43914a5
@ -57,17 +57,39 @@ bool IPv4PortRange::IsMatch(IPv4Port subject) const
|
||||
|
||||
std::string IPv4PortRange::ToString() const
|
||||
{
|
||||
const std::string ip_range = first.ip_address == last.ip_address ?
|
||||
Common::IPAddressToString(first.ip_address) :
|
||||
fmt::format("{}-{}", Common::IPAddressToString(first.ip_address),
|
||||
Common::IPAddressToString(last.ip_address));
|
||||
const u32 first_ip_value = first.GetIPAddressValue();
|
||||
const u32 last_ip_value = last.GetIPAddressValue();
|
||||
const u32 different_bits = first_ip_value ^ last_ip_value;
|
||||
const u32 common_high_bits = std::countl_zero(different_bits);
|
||||
|
||||
std::string ip_range = Common::IPAddressToString(first.ip_address);
|
||||
if (common_high_bits == 32)
|
||||
{
|
||||
// Identical first and last IP.
|
||||
}
|
||||
else if ((last_ip_value - first_ip_value + 1) << common_high_bits == 0)
|
||||
{
|
||||
// An exact network range can use CIDR notation.
|
||||
ip_range = fmt::format("{}/{}", ip_range, common_high_bits);
|
||||
}
|
||||
else if (common_high_bits >= 24)
|
||||
{
|
||||
// Only the last octet is different.
|
||||
ip_range = fmt::format("{}-{}", ip_range, last.ip_address.back());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plainly specified range.
|
||||
ip_range = fmt::format("{}-{}", ip_range, Common::IPAddressToString(last.ip_address));
|
||||
}
|
||||
|
||||
if (first.port == 0)
|
||||
return ip_range;
|
||||
else if (first.port == last.port)
|
||||
|
||||
if (first.port == last.port)
|
||||
return fmt::format("{}:{}", ip_range, first.GetPortValue());
|
||||
else
|
||||
return fmt::format("{}:{}-{}", ip_range, first.GetPortValue(), last.GetPortValue());
|
||||
|
||||
return fmt::format("{}:{}-{}", ip_range, first.GetPortValue(), last.GetPortValue());
|
||||
}
|
||||
|
||||
std::string IPAddressToString(IPAddress ip_address)
|
||||
|
||||
@ -373,6 +373,42 @@ TEST(StringUtil, StringToIPv4PortRange)
|
||||
EXPECT_TRUE(parse("192.168.0.13-14:80-81")->IsMatch(parse("192.168.0.14:81")->first));
|
||||
}
|
||||
|
||||
TEST(StringUtil, IPv4PortRangeToString)
|
||||
{
|
||||
Common::IPv4PortRange subject{
|
||||
.first = {{10, 3, 0, 127}, 0},
|
||||
.last = {{10, 3, 0, 127}, 0},
|
||||
};
|
||||
|
||||
EXPECT_EQ(subject.ToString(), "10.3.0.127");
|
||||
|
||||
subject.last.port = Common::swap16(80); // First port is still zero.
|
||||
EXPECT_EQ(subject.ToString(), "10.3.0.127");
|
||||
|
||||
subject.first.port = Common::swap16(80);
|
||||
EXPECT_EQ(subject.ToString(), "10.3.0.127:80");
|
||||
|
||||
subject.last.port = Common::swap16(88);
|
||||
EXPECT_EQ(subject.ToString(), "10.3.0.127:80-88");
|
||||
|
||||
subject.last.ip_address = {10, 3, 0, 128};
|
||||
EXPECT_EQ(subject.ToString(), "10.3.0.127-128:80-88");
|
||||
|
||||
subject.last.ip_address = {10, 3, 7, 35};
|
||||
EXPECT_EQ(subject.ToString(), "10.3.0.127-10.3.7.35:80-88");
|
||||
|
||||
subject.first.ip_address = {192, 168, 0, 0};
|
||||
subject.last.ip_address = {192, 168, 0, 255};
|
||||
EXPECT_EQ(subject.ToString(), "192.168.0.0/24:80-88");
|
||||
|
||||
subject.last.ip_address = {192, 168, 3, 255};
|
||||
EXPECT_EQ(subject.ToString(), "192.168.0.0/22:80-88");
|
||||
|
||||
subject.first.ip_address = {};
|
||||
subject.last.ip_address = {255, 255, 255, 255};
|
||||
EXPECT_EQ(subject.ToString(), "0.0.0.0/0:80-88");
|
||||
}
|
||||
|
||||
TEST(StringUtil, CharacterEncodingConversion)
|
||||
{
|
||||
// wstring
|
||||
|
||||
Loading…
Reference in New Issue
Block a user