1 #include "util.hpp" 2 3 #include <arpa/inet.h> 4 #include <netinet/in.h> 5 6 #include <cstddef> 7 #include <xyz/openbmc_project/Common/error.hpp> 8 9 #include <gtest/gtest.h> 10 11 namespace phosphor 12 { 13 namespace network 14 { 15 16 using InternalFailure = 17 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 18 class TestUtil : public testing::Test 19 { 20 public: 21 TestUtil() 22 { 23 // Empty 24 } 25 }; 26 27 TEST_F(TestUtil, ToHex) 28 { 29 EXPECT_EQ('E', mac_address::internal::toHex(std::byte(0xfe))); 30 EXPECT_EQ('A', mac_address::internal::toHex(std::byte(10))); 31 EXPECT_EQ('4', mac_address::internal::toHex(std::byte(4))); 32 } 33 34 TEST_F(TestUtil, MacToString) 35 { 36 MacAddr mac1{ 37 std::byte(0x00), std::byte(0xDE), std::byte(0xAD), 38 std::byte(0x00), std::byte(0xBE), std::byte(0xEF), 39 }; 40 EXPECT_EQ("00:DE:AD:00:BE:EF", mac_address::toString(mac1)); 41 MacAddr mac2{ 42 std::byte(0x70), std::byte(0xFF), std::byte(0x84), 43 std::byte(0x09), std::byte(0x35), std::byte(0x09), 44 }; 45 EXPECT_EQ("70:FF:84:09:35:09", mac_address::toString(mac2)); 46 } 47 48 TEST_F(TestUtil, AddrFromBuf) 49 { 50 std::string tooSmall(1, 'a'); 51 std::string tooLarge(24, 'a'); 52 53 struct in_addr ip1; 54 EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1)); 55 std::string_view buf1(reinterpret_cast<char*>(&ip1), sizeof(ip1)); 56 InAddrAny res1 = addrFromBuf(AF_INET, buf1); 57 EXPECT_EQ(0, memcmp(&ip1, &std::get<struct in_addr>(res1), sizeof(ip1))); 58 EXPECT_THROW(addrFromBuf(AF_INET, tooSmall), std::runtime_error); 59 EXPECT_THROW(addrFromBuf(AF_INET, tooLarge), std::runtime_error); 60 EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf1), std::runtime_error); 61 62 struct in6_addr ip2; 63 EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2)); 64 std::string_view buf2(reinterpret_cast<char*>(&ip2), sizeof(ip2)); 65 InAddrAny res2 = addrFromBuf(AF_INET6, buf2); 66 EXPECT_EQ(0, memcmp(&ip2, &std::get<struct in6_addr>(res2), sizeof(ip2))); 67 EXPECT_THROW(addrFromBuf(AF_INET6, tooSmall), std::runtime_error); 68 EXPECT_THROW(addrFromBuf(AF_INET6, tooLarge), std::runtime_error); 69 EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf2), std::runtime_error); 70 } 71 72 TEST_F(TestUtil, IpToString) 73 { 74 struct in_addr ip1; 75 EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1)); 76 EXPECT_EQ("192.168.10.1", toString(InAddrAny(ip1))); 77 78 struct in6_addr ip2; 79 EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2)); 80 EXPECT_EQ("fdd8:b5ad:9d93:94ee::2:1", toString(InAddrAny(ip2))); 81 82 InAddrAny ip3; 83 try 84 { 85 struct E 86 { 87 operator struct in6_addr() 88 { 89 throw 1; 90 } 91 }; 92 ip3.emplace<struct in6_addr>(E()); 93 EXPECT_TRUE(false); 94 } 95 catch (...) 96 { 97 } 98 EXPECT_THROW(toString(ip3), std::runtime_error); 99 } 100 101 TEST_F(TestUtil, IpValidation) 102 { 103 std::string ipaddress = "0.0.0.0"; 104 EXPECT_EQ(true, isValidIP(AF_INET, ipaddress)); 105 106 ipaddress = "9.3.185.83"; 107 EXPECT_EQ(true, isValidIP(AF_INET, ipaddress)); 108 109 ipaddress = "9.3.185.a"; 110 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress)); 111 112 ipaddress = "9.3.a.83"; 113 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress)); 114 115 ipaddress = "x.x.x.x"; 116 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress)); 117 118 ipaddress = "0:0:0:0:0:0:0:0"; 119 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress)); 120 121 ipaddress = "1:0:0:0:0:0:0:8"; 122 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress)); 123 124 ipaddress = "1::8"; 125 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress)); 126 127 ipaddress = "0:0:0:0:0:FFFF:204.152.189.116"; 128 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress)); 129 130 ipaddress = "::ffff:204.152.189.116"; 131 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress)); 132 133 ipaddress = "a:0:0:0:0:FFFF:204.152.189.116"; 134 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress)); 135 136 ipaddress = "1::8"; 137 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress)); 138 } 139 140 TEST_F(TestUtil, PrefixValidation) 141 { 142 uint8_t prefixLength = 1; 143 EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength)); 144 145 prefixLength = 32; 146 EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength)); 147 148 prefixLength = 0; 149 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength)); 150 151 prefixLength = 33; 152 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength)); 153 154 prefixLength = 33; 155 EXPECT_EQ(true, isValidPrefix(AF_INET6, prefixLength)); 156 157 prefixLength = 65; 158 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength)); 159 } 160 161 TEST_F(TestUtil, MacValidation) 162 { 163 std::string macaddress = "00:00:00:00:00:00"; 164 EXPECT_EQ(false, phosphor::network::mac_address::validate(macaddress)); 165 166 macaddress = "F6:C6:E6:6:B0:D3"; 167 EXPECT_EQ(false, phosphor::network::mac_address::validate(macaddress)); 168 169 macaddress = "F6:C6:E6:06:B0:D3"; 170 EXPECT_EQ(true, phosphor::network::mac_address::validate(macaddress)); 171 172 macaddress = "hh:HH:HH:hh:HH:yy"; 173 EXPECT_EQ(false, phosphor::network::mac_address::validate(macaddress)); 174 175 macaddress = "hhh:GGG:iii:jjj:kkk:lll"; 176 EXPECT_EQ(false, phosphor::network::mac_address::validate(macaddress)); 177 } 178 179 TEST_F(TestUtil, ConvertV4MasktoPrefix) 180 { 181 std::string mask = "255.255.255.0"; 182 uint8_t prefix = toCidr(AF_INET, mask); 183 EXPECT_EQ(prefix, 24); 184 185 mask = "255.255.0.0"; 186 prefix = toCidr(AF_INET, mask); 187 EXPECT_EQ(prefix, 16); 188 189 mask = "255.0.0.0"; 190 prefix = toCidr(AF_INET, mask); 191 EXPECT_EQ(prefix, 8); 192 193 mask = "255.224.0.0"; 194 prefix = toCidr(AF_INET, mask); 195 EXPECT_EQ(prefix, 11); 196 197 // Invalid Mask 198 mask = "255.0.255.0"; 199 prefix = toCidr(AF_INET, mask); 200 EXPECT_EQ(prefix, 0); 201 } 202 203 TEST_F(TestUtil, convertV6MasktoPrefix) 204 { 205 std::string mask = "ffff:ffff::"; 206 uint8_t prefix = toCidr(AF_INET6, mask); 207 EXPECT_EQ(prefix, 32); 208 209 mask = "ffff:ffff:ffff::"; 210 prefix = toCidr(AF_INET6, mask); 211 EXPECT_EQ(prefix, 48); 212 213 mask = "ffff:ffff:fc00::"; 214 prefix = toCidr(AF_INET6, mask); 215 EXPECT_EQ(prefix, 38); 216 217 // Invalid Mask 218 mask = "ffff:0fff::"; 219 prefix = toCidr(AF_INET6, mask); 220 EXPECT_EQ(prefix, 0); 221 } 222 223 TEST_F(TestUtil, isLinkLocaladdress) 224 { 225 std::string ipaddress = "fe80:fec0::"; 226 EXPECT_TRUE(isLinkLocalIP(ipaddress)); 227 228 ipaddress = "2000:fe80:789::"; 229 EXPECT_FALSE(isLinkLocalIP(ipaddress)); 230 231 ipaddress = "2000:fe80::"; 232 EXPECT_FALSE(isLinkLocalIP(ipaddress)); 233 234 ipaddress = "169.254.3.3"; 235 EXPECT_TRUE(isLinkLocalIP(ipaddress)); 236 237 ipaddress = "3.169.254.3"; 238 EXPECT_FALSE(isLinkLocalIP(ipaddress)); 239 240 ipaddress = "3.3.169.254"; 241 EXPECT_FALSE(isLinkLocalIP(ipaddress)); 242 } 243 244 TEST_F(TestUtil, convertPrefixToMask) 245 { 246 std::string mask = toMask(AF_INET, 24); 247 EXPECT_EQ(mask, "255.255.255.0"); 248 249 mask = toMask(AF_INET, 8); 250 EXPECT_EQ(mask, "255.0.0.0"); 251 252 mask = toMask(AF_INET, 27); 253 EXPECT_EQ(mask, "255.255.255.224"); 254 } 255 256 TEST_F(TestUtil, getNetworkAddress) 257 { 258 std::string address = getNetworkID(AF_INET, "9.3.23.251", 24); 259 EXPECT_EQ("9.3.23.0", address); 260 261 address = getNetworkID(AF_INET, "9.3.23.251", 25); 262 EXPECT_EQ("9.3.23.128", address); 263 264 address = getNetworkID(AF_INET6, "2001:db8:abcd:dd12::0", 64); 265 EXPECT_EQ("2001:db8:abcd:dd12::", address); 266 267 EXPECT_THROW(getNetworkID(AF_INET, "a.b.c.d", 25), InternalFailure); 268 269 EXPECT_THROW(getNetworkID(AF_INET6, "2001:db8:gghh:dd12::0", 64), 270 InternalFailure); 271 272 address = getNetworkID(AF_INET6, "fe80::201:6cff:fe80:228", 64); 273 EXPECT_EQ("fe80::", address); 274 } 275 276 } // namespace network 277 } // namespace phosphor 278