1 #include "types.hpp" 2 3 #include <arpa/inet.h> 4 #include <fmt/chrono.h> 5 #include <fmt/format.h> 6 7 #include <array> 8 #include <sstream> 9 #include <string_view> 10 11 #include <gtest/gtest.h> 12 13 using std::literals::string_view_literals::operator""sv; 14 15 TEST(EqualOperator, EthAddr) 16 { 17 EXPECT_EQ((ether_addr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}), 18 (ether_addr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66})); 19 EXPECT_EQ((ether_addr{}), (ether_addr{})); 20 EXPECT_NE((ether_addr{1}), (ether_addr{})); 21 } 22 23 TEST(EqualOperator, InAddr) 24 { 25 EXPECT_EQ((in_addr{0xff00ff00}), (in_addr{0xff00ff00})); 26 EXPECT_EQ((in_addr{}), (in_addr{})); 27 EXPECT_NE((in_addr{1}), (in_addr{})); 28 } 29 30 TEST(EqualOperator, In6Addr) 31 { 32 EXPECT_EQ((in6_addr{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff}), 33 (in6_addr{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff})); 34 EXPECT_EQ((in6_addr{}), (in6_addr{})); 35 EXPECT_NE((in6_addr{1}), (in6_addr{})); 36 } 37 38 namespace phosphor::network 39 { 40 41 TEST(Byteswap, Swap) 42 { 43 EXPECT_EQ(38, bswap(uint8_t{38})); 44 EXPECT_EQ(38 << 8, bswap(uint16_t{38})); 45 EXPECT_EQ(0x240082fe, bswap(uint32_t{0xfe820024})); 46 EXPECT_EQ(0x240082fe00000000, bswap(uint64_t{0xfe820024})); 47 struct 48 { 49 std::array<char, 4> a = {1, 2, 3, 4}; 50 } s; 51 EXPECT_EQ((std::array<char, 4>{4, 3, 2, 1}), bswap(s).a); 52 } 53 54 TEST(DecodeInt, uint8_10) 55 { 56 DecodeInt<uint8_t, 10> d; 57 EXPECT_EQ(42, d("42")); 58 EXPECT_EQ(255, d("255")); 59 EXPECT_THROW(d(""), std::invalid_argument); 60 EXPECT_THROW(d("a0"), std::invalid_argument); 61 EXPECT_THROW(d(".0"), std::invalid_argument); 62 EXPECT_THROW(d("257"), std::overflow_error); 63 EXPECT_THROW(d("300"), std::overflow_error); 64 } 65 66 TEST(DecodeInt, uint8_16) 67 { 68 DecodeInt<uint8_t, 16> d; 69 EXPECT_EQ(0x42, d("42")); 70 EXPECT_EQ(0xff, d("ff")); 71 EXPECT_THROW(d(""), std::invalid_argument); 72 EXPECT_THROW(d("g0"), std::invalid_argument); 73 EXPECT_THROW(d(".0"), std::invalid_argument); 74 EXPECT_THROW(d("100"), std::overflow_error); 75 } 76 77 TEST(EncodeInt, uint8_10) 78 { 79 EncodeInt<uint8_t, 10> e; 80 static_assert(e.buf_size == 3); 81 char buf[e.buf_size]; 82 EXPECT_EQ("0", std::string_view(buf, e(buf, 0))); 83 EXPECT_EQ("42", std::string_view(buf, e(buf, 42))); 84 EXPECT_EQ("255", std::string_view(buf, e(buf, 255))); 85 EXPECT_EQ("000", std::string_view(buf, e(buf, 0, 3))); 86 EXPECT_EQ("255", std::string_view(buf, e(buf, 255, 3))); 87 } 88 89 TEST(EncodeInt, uint8_16) 90 { 91 EncodeInt<uint8_t, 16> e; 92 static_assert(e.buf_size == 2); 93 char buf[e.buf_size]; 94 EXPECT_EQ("0", std::string_view(buf, e(buf, 0))); 95 EXPECT_EQ("2a", std::string_view(buf, e(buf, 42))); 96 EXPECT_EQ("ff", std::string_view(buf, e(buf, 255))); 97 EXPECT_EQ("00", std::string_view(buf, e(buf, 0, 2))); 98 EXPECT_EQ("02", std::string_view(buf, e(buf, 2, 2))); 99 EXPECT_EQ("ff", std::string_view(buf, e(buf, 255, 2))); 100 } 101 102 TEST(EqualOperator, InAddrAny) 103 { 104 EXPECT_EQ(InAddrAny(in6_addr{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105 0xff}), 106 (in6_addr{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff})); 107 EXPECT_NE(InAddrAny(in6_addr{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108 0xff}), 109 (in_addr{})); 110 EXPECT_EQ((in6_addr{}), InAddrAny(in6_addr{})); 111 EXPECT_NE((in_addr{}), InAddrAny(in6_addr{})); 112 EXPECT_NE(InAddrAny(in6_addr{1}), InAddrAny(in6_addr{})); 113 } 114 115 TEST(ToAddr, EtherAddr) 116 { 117 EXPECT_THROW(ToAddr<ether_addr>{}("0x:00:00:00:00:00"), 118 std::invalid_argument); 119 EXPECT_THROW(ToAddr<ether_addr>{}("00:00:00:00:00"), std::invalid_argument); 120 EXPECT_THROW(ToAddr<ether_addr>{}("00:00:00:00:00:"), 121 std::invalid_argument); 122 EXPECT_THROW(ToAddr<ether_addr>{}("00:00:00:00::00"), 123 std::invalid_argument); 124 EXPECT_THROW(ToAddr<ether_addr>{}(":00:00:00:00:00"), 125 std::invalid_argument); 126 EXPECT_THROW(ToAddr<ether_addr>{}("00::00:00:00:00"), 127 std::invalid_argument); 128 EXPECT_THROW(ToAddr<ether_addr>{}(":::::"), std::invalid_argument); 129 EXPECT_THROW(ToAddr<ether_addr>{}("00:0:0:0:0"), std::invalid_argument); 130 EXPECT_THROW(ToAddr<ether_addr>{}("00:00:00:00:00:00:00"), 131 std::invalid_argument); 132 EXPECT_THROW(ToAddr<ether_addr>{}(""), std::invalid_argument); 133 EXPECT_THROW(ToAddr<ether_addr>{}("123456789XYZ"), std::invalid_argument); 134 EXPECT_THROW(ToAddr<ether_addr>{}("123456789AB"), std::overflow_error); 135 EXPECT_THROW(ToAddr<ether_addr>{}("123456789ABCD"), std::overflow_error); 136 137 EXPECT_EQ((ether_addr{}), ToAddr<ether_addr>{}("00:00:00:00:00:00")); 138 EXPECT_EQ((ether_addr{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}), 139 ToAddr<ether_addr>{}("FF:EE:DD:cc:bb:aa")); 140 EXPECT_EQ((ether_addr{0x00, 0x01, 0x02, 0x03, 0x04, 0x05}), 141 ToAddr<ether_addr>{}("0:1:2:3:4:5")); 142 EXPECT_EQ((ether_addr{0x01, 0x23, 0x45, 0x67, 0x89, 0xab}), 143 ToAddr<ether_addr>{}("0123456789AB")); 144 EXPECT_EQ((ether_addr{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}), 145 ToAddr<ether_addr>{}("FFEEDDccbbaa")); 146 } 147 148 TEST(ToAddr, InAddr) 149 { 150 EXPECT_THROW(ToAddr<in_addr>{}(""), std::invalid_argument); 151 EXPECT_THROW(ToAddr<in_addr>{}("0"), std::invalid_argument); 152 EXPECT_THROW(ToAddr<in_addr>{}("0.0.0"), std::invalid_argument); 153 EXPECT_THROW(ToAddr<in_addr>{}("0.0.0."), std::invalid_argument); 154 EXPECT_THROW(ToAddr<in_addr>{}(".0.0.0"), std::invalid_argument); 155 EXPECT_THROW(ToAddr<in_addr>{}("0.0.0.0.0"), std::invalid_argument); 156 EXPECT_THROW(ToAddr<in_addr>{}("x.0.0.0"), std::invalid_argument); 157 EXPECT_THROW(ToAddr<in_addr>{}("ff.0.0.0"), std::invalid_argument); 158 EXPECT_THROW(ToAddr<in_addr>{}("256.0.0.0"), std::overflow_error); 159 160 EXPECT_EQ((in_addr{}), ToAddr<in_addr>{}("0.0.0.0")); 161 EXPECT_EQ((in_addr{htonl(0xc0a80101)}), ToAddr<in_addr>{}("192.168.001.1")); 162 } 163 164 TEST(ToAddr, In6Addr) 165 { 166 constexpr ToAddr<in6_addr> ta; 167 EXPECT_THROW(ta(""), std::invalid_argument); 168 EXPECT_THROW(ta("0"), std::invalid_argument); 169 EXPECT_THROW(ta("0:0"), std::invalid_argument); 170 EXPECT_THROW(ta("0::0:"), std::invalid_argument); 171 EXPECT_THROW(ta("0:::"), std::invalid_argument); 172 EXPECT_THROW(ta(":::0"), std::invalid_argument); 173 EXPECT_THROW(ta("0:::0"), std::invalid_argument); 174 EXPECT_THROW(ta("0::0::0"), std::invalid_argument); 175 EXPECT_THROW(ta("1::0.0.0."), std::invalid_argument); 176 EXPECT_THROW(ta("1::.0.0.0"), std::invalid_argument); 177 EXPECT_THROW(ta("x::0"), std::invalid_argument); 178 EXPECT_THROW(ta("g::0"), std::invalid_argument); 179 EXPECT_THROW(ta("0:1:2:3:4::5:6:7"), std::invalid_argument); 180 EXPECT_THROW(ta("::0:1:2:3:4:5:6:7"), std::invalid_argument); 181 EXPECT_THROW(ta("0:1:2:3:4:5:6:7::"), std::invalid_argument); 182 EXPECT_THROW(ta("0:1:2:3:4:5:6:7:8"), std::invalid_argument); 183 EXPECT_THROW(ta("0:1:2:3:4:5:6:0.0.0.0"), std::invalid_argument); 184 EXPECT_THROW(ta("0:1:2:3:4:5::0.0.0.0"), std::invalid_argument); 185 EXPECT_THROW(ta("ffff0::0"), std::overflow_error); 186 187 EXPECT_EQ((in6_addr{}), ta("::")); 188 EXPECT_EQ((in6_addr{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 189 255, 255, 255, 255, 255}), 190 ta("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"sv)); 191 EXPECT_EQ((in6_addr{}), ta("0:0:0:0:0:0:0:0")); 192 EXPECT_EQ((in6_addr{0, 0xff}), ta("ff::")); 193 EXPECT_EQ((in6_addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff}), 194 ta("::ff")); 195 EXPECT_EQ((in6_addr{0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff}), 196 ta("0:0:ff::ff")); 197 EXPECT_EQ((in6_addr{0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8}), 198 ta("1:2:3:4::6:7:8")); 199 EXPECT_EQ((in6_addr{0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0}), 200 ta("1:2:3:4:5:6:7::")); 201 EXPECT_EQ((in6_addr{0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8}), 202 ta("::2:3:4:5:6:7:8")); 203 EXPECT_EQ( 204 (in6_addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 0, 1}), 205 ta("::ffff:192.168.0.1")); 206 EXPECT_EQ((in6_addr{0, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 168, 0, 1}), 207 ta("ff::255.168.0.1")); 208 EXPECT_EQ((in6_addr{0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 255, 168, 0, 1}), 209 ta("0:1:2:3:4:5:255.168.0.1")); 210 } 211 212 TEST(ToAddr, InAddrAny) 213 { 214 constexpr ToAddr<InAddrAny> ta; 215 EXPECT_EQ((InAddrAny{in_addr{}}), ta("0.0.0.0")); 216 EXPECT_EQ((InAddrAny{in6_addr{}}), ta("::")); 217 EXPECT_EQ((InAddrAny{in6_addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 218 168, 0, 1}}), 219 ta("::ffff:192.168.0.1")); 220 } 221 222 TEST(ToAddr, IfAddr) 223 { 224 constexpr ToAddr<IfAddr> ta; 225 EXPECT_THROW(ta("10"), std::invalid_argument); 226 EXPECT_THROW(ta("/10"), std::invalid_argument); 227 EXPECT_THROW(ta("0.0.0.0"), std::invalid_argument); 228 EXPECT_THROW(ta("0.0.0.0/"), std::invalid_argument); 229 EXPECT_EQ((IfAddr{in_addr{}, 0}), ta("0.0.0.0/0")); 230 EXPECT_EQ((IfAddr{in_addr{}, 30}), ta("0.0.0.0/30")); 231 EXPECT_EQ((IfAddr{in6_addr{}, 80}), ta("::/80")); 232 } 233 234 namespace detail 235 { 236 237 TEST(BufMaker, EthAddr) 238 { 239 ToStrBuf<ether_addr> abm; 240 EXPECT_EQ("11:22:33:44:55:66"sv, 241 abm(ether_addr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66})); 242 EXPECT_EQ("01:02:03:04:05:67"sv, 243 abm(ether_addr{0x01, 0x02, 0x03, 0x04, 0x05, 0x67})); 244 EXPECT_EQ("00:00:00:00:00:00"sv, 245 abm(ether_addr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); 246 } 247 248 TEST(BufMaker, InAddr) 249 { 250 ToStrBuf<in_addr> abm; 251 EXPECT_EQ("255.255.255.255"sv, abm(in_addr{0xffffffff})); 252 EXPECT_EQ("1.15.3.4"sv, abm(in_addr{htonl(0x010f0304)})); 253 EXPECT_EQ("0.0.0.0"sv, abm(in_addr{})); 254 } 255 256 TEST(BufMaker, In6Addr) 257 { 258 ToStrBuf<in6_addr> abm; 259 EXPECT_EQ("::"sv, abm(in6_addr{})); 260 EXPECT_EQ("ff::"sv, abm(in6_addr{0, 0xff})); 261 EXPECT_EQ("::ff"sv, 262 abm(in6_addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff})); 263 EXPECT_EQ("0:0:ff::ff"sv, abm(in6_addr{0, 0, 0, 0, 0, 0xff, 0, 0, 0, 0, 0, 264 0, 0, 0, 0, 0xff})); 265 EXPECT_EQ("::100:0:ff"sv, 266 abm(in6_addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0xff})); 267 EXPECT_EQ("ff00::"sv, abm(in6_addr{0xff})); 268 EXPECT_EQ("1:2:3:4:5:6:7:8"sv, 269 abm(in6_addr{0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8})); 270 EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"sv, 271 abm(in6_addr{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 272 255, 255, 255, 255, 255, 255})); 273 // rfc5952 4.2.2 274 EXPECT_EQ("1:2:3:4:0:6:7:8"sv, 275 abm(in6_addr{0, 1, 0, 2, 0, 3, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8})); 276 // rfc5952 4.2.3 277 EXPECT_EQ("1::4:0:0:7:8"sv, 278 abm(in6_addr{0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 7, 0, 8})); 279 // rfc5952 5 280 EXPECT_EQ("::ffff:192.168.0.1"sv, 281 abm(in6_addr{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 282 0, 1})); 283 } 284 285 TEST(BasicOps, AllAddrs) 286 { 287 EXPECT_NE(InAddrAny{in6_addr{}}, InAddrAny{in_addr{}}); 288 289 EXPECT_EQ("a 01:00:00:00:00:00", fmt::format("a {}", ether_addr{1})); 290 EXPECT_EQ("a 0.0.0.1", fmt::format("a {}", in_addr{htonl(1)})); 291 EXPECT_EQ("a 0.0.0.1", fmt::format("a {}", InAddrAny{in_addr{htonl(1)}})); 292 EXPECT_EQ("a 100::", fmt::format("a {}", in6_addr{1})); 293 EXPECT_EQ("a 100::", fmt::format("a {}", InAddrAny{in6_addr{1}})); 294 EXPECT_EQ("a 100::/90", fmt::format("a {}", IfAddr{in6_addr{1}, 90})); 295 296 EXPECT_EQ("01:00:00:00:00:00", std::to_string(ether_addr{1})); 297 EXPECT_EQ("0.0.0.1", std::to_string(in_addr{htonl(1)})); 298 EXPECT_EQ("0.0.0.1", std::to_string(InAddrAny{in_addr{htonl(1)}})); 299 EXPECT_EQ("100::", std::to_string(in6_addr{1})); 300 EXPECT_EQ("100::", std::to_string(InAddrAny{in6_addr{1}})); 301 EXPECT_EQ("100::/22", std::to_string(IfAddr{in6_addr{1}, 22})); 302 303 EXPECT_EQ("a01:00:00:00:00:00", 304 (std::stringstream{} << "a" << ether_addr{1}).str()); 305 EXPECT_EQ("a0.0.0.1", 306 (std::stringstream{} << "a" << in_addr{htonl(1)}).str()); 307 EXPECT_EQ( 308 "a0.0.0.1", 309 (std::stringstream{} << "a" << InAddrAny{in_addr{htonl(1)}}).str()); 310 EXPECT_EQ("a100::", (std::stringstream{} << "a" << in6_addr{1}).str()); 311 EXPECT_EQ("a100::", 312 (std::stringstream{} << "a" << InAddrAny{in6_addr{1}}).str()); 313 auto ss = std::stringstream{}; 314 constexpr auto addr = IfAddr{in6_addr{1}, 30}; 315 ss << "a" << addr; 316 EXPECT_EQ("a100::/30", ss.str()); 317 318 EXPECT_NO_THROW(IfAddr(in6_addr{}, 128)); 319 EXPECT_NO_THROW(IfAddr(in_addr{}, 32)); 320 EXPECT_THROW(IfAddr(in6_addr{}, 129), std::invalid_argument); 321 EXPECT_THROW(IfAddr(in_addr{}, 33), std::invalid_argument); 322 } 323 324 TEST(Perf, In6Addr) 325 { 326 GTEST_SKIP(); 327 auto start = std::chrono::steady_clock::now(); 328 for (size_t i = 0; i < 10000000; ++i) 329 { 330 ToStrBuf<in6_addr>{}(in6_addr{1}); 331 } 332 fmt::print("Duration: {}\n", std::chrono::steady_clock::now() - start); 333 // Make sure this test isn't enabled 334 EXPECT_FALSE(true); 335 } 336 337 } // namespace detail 338 } // namespace phosphor::network 339