diff --git a/common/ipaddress.cpp b/common/ipaddress.cpp index f31d11803..6af5754f6 100644 --- a/common/ipaddress.cpp +++ b/common/ipaddress.cpp @@ -45,11 +45,14 @@ IpAddress::AddrScope IpAddress::getAddrScope() const static const IpAddress ipv6LinkScopeAddress = IpAddress("FE80::0"); static const IpAddress ipv4HostScopeAddress = IpAddress("127.0.0.1"); static const IpAddress ipv6HostScopeAddress = IpAddress("::1"); + static const IpAddress ipv4McastScopeAddress = IpAddress("224.0.0.0"); + static const IpAddress ipv6McastScopeAddress = IpAddress("FF00::0"); if (isV4()) { const uint32_t ip1 = htonl(getV4Addr()); const uint32_t ip2 = htonl(ipv4LinkScopeAddress.getV4Addr()); + const uint32_t ip3 = htonl(ipv4McastScopeAddress.getV4Addr()); /* IPv4 local-scope mask is 16 bits long -- mask = 0xffff0000 */ if ((ip1 & 0xffff0000) == ip2) @@ -60,11 +63,17 @@ IpAddress::AddrScope IpAddress::getAddrScope() const { return HOST_SCOPE; } + /* IPv4 multicast-scope mask is 4 bits long -- mask = 0xf0000000 */ + else if ((ip1 & 0xf0000000) == ip3) + { + return MCAST_SCOPE; + } } else { const uint8_t *ip1 = getV6Addr(); const uint8_t *ip2 = ipv6LinkScopeAddress.getV6Addr(); + const uint8_t *ip3 = ipv6McastScopeAddress.getV6Addr(); /* IPv6 local-scope mask is 10 bits long -- mask = 0xffc0::0 */ if ((ip1[0] == ip2[0]) && ((ip1[1] & 0xc0) == ip2[1])) @@ -75,6 +84,11 @@ IpAddress::AddrScope IpAddress::getAddrScope() const { return HOST_SCOPE; } + /* IPv6 multicast-scope mask is 8 bits long -- mask = 0xff00::0 */ + else if (ip1[0] == ip3[0]) + { + return MCAST_SCOPE; + } } return GLOBAL_SCOPE; diff --git a/common/ipaddress.h b/common/ipaddress.h index 3973223c0..bf890e435 100644 --- a/common/ipaddress.h +++ b/common/ipaddress.h @@ -77,7 +77,8 @@ class IpAddress enum AddrScope { GLOBAL_SCOPE, LINK_SCOPE, - HOST_SCOPE + HOST_SCOPE, + MCAST_SCOPE }; IpAddress::AddrScope getAddrScope() const; diff --git a/common/ipprefix.h b/common/ipprefix.h index 47aed33fe..03ad68e8a 100644 --- a/common/ipprefix.h +++ b/common/ipprefix.h @@ -96,6 +96,14 @@ class IpPrefix return (m_mask == 0); } + inline bool isFullMask() const + { + if (m_ip.isV4()) + return (m_mask == 32); + else + return (m_mask == 128); + } + inline bool isAddressInSubnet(const IpAddress& addr) const { if (m_ip.getIp().family != addr.getIp().family) diff --git a/tests/ipaddress_ut.cpp b/tests/ipaddress_ut.cpp index fbc8e2c4d..12ecf0486 100644 --- a/tests/ipaddress_ut.cpp +++ b/tests/ipaddress_ut.cpp @@ -44,6 +44,8 @@ TEST(IpAddress, getAddrScope) IpAddress ip5("169.253.1.1"); IpAddress ip6("169.255.1.1"); IpAddress ip7("127.0.0.1"); + IpAddress ip8("224.0.0.1"); + IpAddress ip9("239.255.255.255"); // IPv6 prefixes IpAddress ip11("2001:4898:f0:f153:357c:77b2:49c9:627c"); @@ -54,6 +56,8 @@ TEST(IpAddress, getAddrScope) IpAddress ip16("febf:1::1"); IpAddress ip17("fec0:1::1"); IpAddress ip18("::1"); + IpAddress ip19("ff00::1"); + IpAddress ip20("ffff:1::1"); EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip1.getAddrScope()); EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip2.getAddrScope()); @@ -62,6 +66,8 @@ TEST(IpAddress, 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::MCAST_SCOPE, ip8.getAddrScope()); + EXPECT_EQ(IpAddress::AddrScope::MCAST_SCOPE, ip9.getAddrScope()); EXPECT_EQ(IpAddress::AddrScope::GLOBAL_SCOPE, ip11.getAddrScope()); EXPECT_EQ(IpAddress::AddrScope::LINK_SCOPE, ip12.getAddrScope()); @@ -71,4 +77,6 @@ TEST(IpAddress, 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()); + EXPECT_EQ(IpAddress::AddrScope::MCAST_SCOPE, ip19.getAddrScope()); + EXPECT_EQ(IpAddress::AddrScope::MCAST_SCOPE, ip20.getAddrScope()); } diff --git a/tests/ipprefix_ut.cpp b/tests/ipprefix_ut.cpp index 26d60fbce..65f5ddc22 100644 --- a/tests/ipprefix_ut.cpp +++ b/tests/ipprefix_ut.cpp @@ -144,3 +144,34 @@ TEST(IpPrefix, getSubnet) EXPECT_EQ("2001:4898:f0::/45", prefix9.getSubnet().to_string()); EXPECT_EQ("2001:4898:f0:f153:357c:77b2:49c9:627c/128", prefix10.getSubnet().to_string()); } + +TEST(IpPrefix, maskLen) +{ + IpPrefix prefix1("0.0.0.0/0"); + IpPrefix prefix2("1.1.1.1/24"); + IpPrefix prefix3("1.1.1.1/32"); + IpPrefix prefix4("::/0"); + IpPrefix prefix5("2001:4898:f0:f153:357c:77b2:49c9:627c/64"); + IpPrefix prefix6("2001:4898:f0:f153:357c:77b2:49c9:627c/128"); + + EXPECT_TRUE(prefix1.isDefaultRoute()); + EXPECT_FALSE(prefix2.isDefaultRoute()); + EXPECT_FALSE(prefix3.isDefaultRoute()); + EXPECT_TRUE(prefix4.isDefaultRoute()); + EXPECT_FALSE(prefix5.isDefaultRoute()); + EXPECT_FALSE(prefix6.isDefaultRoute()); + + EXPECT_FALSE(prefix1.isFullMask()); + EXPECT_FALSE(prefix2.isFullMask()); + EXPECT_TRUE(prefix3.isFullMask()); + EXPECT_FALSE(prefix4.isFullMask()); + EXPECT_FALSE(prefix5.isFullMask()); + EXPECT_TRUE(prefix6.isFullMask()); + + EXPECT_EQ(0, prefix1.getMaskLength()); + EXPECT_EQ(24, prefix2.getMaskLength()); + EXPECT_EQ(32, prefix3.getMaskLength()); + EXPECT_EQ(0, prefix4.getMaskLength()); + EXPECT_EQ(64, prefix5.getMaskLength()); + EXPECT_EQ(128, prefix6.getMaskLength()); +} \ No newline at end of file