Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions common/ipaddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,45 @@ std::string IpAddress::to_string() const

return ipStr;
}

IpAddress::AddrScope IpAddress::getAddrScope() const
{
/* Auxiliary prefixes used to determine the scope of any given address */
static const IpAddress ipv4LinkScopeAddress = IpAddress("169.254.0.0");
static const IpAddress ipv6LinkScopeAddress = IpAddress("FE80::0");
static const IpAddress ipv4HostScopeAddress = IpAddress("127.0.0.1");
static const IpAddress ipv6HostScopeAddress = IpAddress("::1");

if (isV4())
{
const uint32_t ip1 = htonl(getV4Addr());
const uint32_t ip2 = htonl(ipv4LinkScopeAddress.getV4Addr());

/* IPv4 local-scope mask is 16 bits long -- mask = 0xffff0000 */
if ((ip1 & 0xffff0000) == ip2)
{
return LINK_SCOPE;
}
else if (*this == ipv4HostScopeAddress)
{
return HOST_SCOPE;
}
}
else
{
const uint8_t *ip1 = getV6Addr();
const uint8_t *ip2 = ipv6LinkScopeAddress.getV6Addr();

/* IPv6 local-scope mask is 10 bits long -- mask = 0xffc0::0 */
if ((ip1[0] == ip2[0]) && ((ip1[1] & 0xc0) == ip2[1]))
{
return LINK_SCOPE;
}
else if (*this == ipv6HostScopeAddress)
{
return HOST_SCOPE;
}
}

return GLOBAL_SCOPE;
}
8 changes: 8 additions & 0 deletions common/ipaddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ class IpAddress

std::string to_string() const;

enum AddrScope {
GLOBAL_SCOPE,
LINK_SCOPE,
HOST_SCOPE
};

IpAddress::AddrScope getAddrScope() const;

private:
struct ip_addr_t m_ip;
};
Expand Down
39 changes: 39 additions & 0 deletions tests/ipaddress_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,42 @@ TEST(IpAddresses, contains)
EXPECT_TRUE(ips.contains(ips_1));
EXPECT_FALSE(ips.contains(ips_2));
}

TEST(IpAddress, getAddrScope)
{
// IPv4 prefixes
IpAddress ip1("0.0.0.0");
IpAddress ip2("169.1.1.1");
IpAddress ip3("169.254.0.1");
IpAddress ip4("169.254.255.255");
IpAddress ip5("169.253.1.1");
IpAddress ip6("169.255.1.1");
IpAddress ip7("127.0.0.1");

// IPv6 prefixes
IpAddress ip11("2001:4898:f0:f153:357c:77b2:49c9:627c");
IpAddress ip12("fe80::1");
IpAddress ip13("fe80:1:1:1:1:1:1:1");
IpAddress ip14("fe99::1");
IpAddress ip15("feb0:1::1");
IpAddress ip16("febf:1::1");
IpAddress ip17("fec0:1::1");
IpAddress ip18("::1");

EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip1.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip2.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip3.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip4.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip5.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip6.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::HOST_SCOPE, ip7.getAddrScope());

EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip11.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip12.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip13.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip14.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip15.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip16.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip17.getAddrScope());
EXPECT_EQ(IpAddress::AddrScope::HOST_SCOPE, ip18.getAddrScope());
}