blob: 8973bdbcdf2656bce3b8314f3a09c71d67970667 [file] [log] [blame]
William A. Kennington III14dd4eb2023-01-12 10:51:12 -08001#include <fmt/format.h>
2
3#include <stdplus/net/addr/subnet.hpp>
4
William A. Kennington III5b20b0a2023-07-18 13:38:37 -07005#include <format>
William A. Kennington III160e3822023-06-16 17:09:43 -07006#include <string_view>
7
William A. Kennington III14dd4eb2023-01-12 10:51:12 -08008#include <gtest/gtest.h>
9
William A. Kennington III160e3822023-06-16 17:09:43 -070010using std::literals::string_view_literals::operator""sv;
11
William A. Kennington III14dd4eb2023-01-12 10:51:12 -080012namespace stdplus
13{
14
15auto addr4Full = In4Addr{255, 255, 255, 255};
16auto addr6Full = In6Addr{255, 255, 255, 255, 255, 255, 255, 255,
17 255, 255, 255, 255, 255, 255, 255, 255};
18
19TEST(Subnet4, Basic)
20{
21 EXPECT_NO_THROW(Subnet4(in_addr{0xffffffff}, 32));
22 EXPECT_NO_THROW(Subnet4(addr4Full, 0));
23 EXPECT_NO_THROW(Subnet4(in_addr{}, 10));
24 EXPECT_THROW(Subnet4(in_addr{0xffffffff}, 33), std::invalid_argument);
25 EXPECT_THROW(Subnet4(in_addr{0xffffffff}, 64), std::invalid_argument);
26
27 EXPECT_NE(Subnet4(in_addr{0xff}, 32), Subnet4(in_addr{}, 32));
28 EXPECT_NE(Subnet4(in_addr{0xff}, 26), Subnet4(in_addr{0xff}, 27));
29 EXPECT_EQ(Subnet4(in_addr{0xff}, 32), Subnet4(in_addr{0xff}, 32));
30 EXPECT_EQ(Subnet4(in_addr{}, 1), Subnet4(in_addr{}, 1));
31}
32
33TEST(Subnet4, Network)
34{
35 EXPECT_EQ((In4Addr{}), Subnet4(In4Addr{}, 32).network());
36 EXPECT_EQ(addr4Full, Subnet4(addr4Full, 32).network());
37 EXPECT_EQ((In4Addr{255, 255, 128, 0}), Subnet4(addr4Full, 17).network());
38 EXPECT_EQ((In4Addr{255, 255, 0, 0}), Subnet4(addr4Full, 16).network());
39 EXPECT_EQ((In4Addr{255, 254, 0, 0}), Subnet4(addr4Full, 15).network());
40 EXPECT_EQ((In4Addr{}), Subnet4(addr4Full, 0).network());
41 EXPECT_EQ((In4Addr{}), Subnet4(In4Addr{}, 0).network());
42}
43
44TEST(Subnet4, Contains)
45{
46 EXPECT_TRUE(Subnet4(addr4Full, 32).contains(addr4Full));
47 EXPECT_FALSE(Subnet4(addr4Full, 32).contains(In4Addr{255, 255, 255, 254}));
48 EXPECT_FALSE(Subnet4(addr4Full, 32).contains(In4Addr{}));
49 EXPECT_TRUE(
50 Subnet4(addr4Full, 17).contains(static_cast<in_addr>(addr4Full)));
51 EXPECT_TRUE(Subnet4(addr4Full, 17).contains(In4Addr{255, 255, 128, 134}));
52 EXPECT_FALSE(Subnet4(addr4Full, 17).contains(In4Addr{255, 255, 127, 132}));
53 EXPECT_TRUE(Subnet4(addr4Full, 14).contains(addr4Full));
54 EXPECT_TRUE(Subnet4(addr4Full, 0).contains(addr4Full));
55 EXPECT_TRUE(Subnet4(In4Addr{}, 0).contains(addr4Full));
56 EXPECT_TRUE(Subnet4(addr4Full, 0).contains(In4Addr{}));
57}
58
William A. Kennington III160e3822023-06-16 17:09:43 -070059TEST(Subnet4, FromStr)
60{
61 constexpr FromStr<Subnet4> fs;
62 EXPECT_THROW(fs("10"sv), std::invalid_argument);
63 EXPECT_THROW(fs("/10"sv), std::invalid_argument);
64 EXPECT_THROW(fs("0.0.0.0"sv), std::invalid_argument);
65 EXPECT_THROW(fs("0.0.0.0/"sv), std::invalid_argument);
66 EXPECT_THROW(fs("::/80"sv), std::invalid_argument);
67 EXPECT_EQ((SubnetAny{in_addr{}, 30}), fs("0.0.0.0/30"sv));
William A. Kennington III39011c82023-06-28 17:49:30 -070068 EXPECT_EQ((SubnetAny{in_addr{}, 30}), "0.0.0.0/30"_sub4);
William A. Kennington III160e3822023-06-16 17:09:43 -070069}
70
William A. Kennington IIId5957f52023-06-16 16:55:01 -070071TEST(Subnet4, ToStr)
72{
73 ToStrHandle<ToStr<Subnet4>> tsh;
74 EXPECT_EQ("0.0.0.0/16", tsh(Subnet4({}, 16)));
75 EXPECT_EQ("255.0.255.255/28", tsh(Subnet4(In4Addr{255, 0, 255, 255}, 28)));
76 EXPECT_EQ("a 1.2.3.4/32 b",
77 fmt::format("a {} b", Subnet4(In4Addr{1, 2, 3, 4}, 32)));
William A. Kennington III5b20b0a2023-07-18 13:38:37 -070078 EXPECT_EQ("a 1.2.3.4/32 b",
79 std::format("a {} b", Subnet4(In4Addr{1, 2, 3, 4}, 32)));
William A. Kennington IIId5957f52023-06-16 16:55:01 -070080}
81
William A. Kennington III14dd4eb2023-01-12 10:51:12 -080082TEST(Subnet6, Basic)
83{
84 EXPECT_NO_THROW(Subnet6(in6_addr{0xff}, 128));
85 EXPECT_NO_THROW(Subnet6(addr6Full, 0));
86 EXPECT_NO_THROW(Subnet6(in6_addr{}, 65));
87 EXPECT_THROW(Subnet6(in6_addr{0xff}, 129), std::invalid_argument);
88 EXPECT_THROW(Subnet6(in6_addr{0xff}, 150), std::invalid_argument);
89
90 EXPECT_NE(Subnet6(in6_addr{0xff}, 32), Subnet6(in6_addr{}, 32));
91 EXPECT_NE(Subnet6(in6_addr{0xff}, 26), Subnet6(in6_addr{0xff}, 27));
92 EXPECT_EQ(Subnet6(in6_addr{0xff}, 32), Subnet6(in6_addr{0xff}, 32));
93 EXPECT_EQ(Subnet6(in6_addr{}, 1), Subnet6(in6_addr{}, 1));
94}
95
96TEST(Subnet6, Network)
97{
98 EXPECT_EQ(In6Addr(), Subnet6(In6Addr(), 128).network());
99 EXPECT_EQ(addr6Full, Subnet6(addr6Full, 128).network());
100 EXPECT_EQ((In6Addr{255, 255, 255, 255, 224}),
101 Subnet6(addr6Full, 35).network());
102 EXPECT_EQ((In6Addr{255, 255, 255, 255}), Subnet6(addr6Full, 32).network());
103 EXPECT_EQ((In6Addr{255, 255, 128, 0}), Subnet6(addr6Full, 17).network());
104 EXPECT_EQ((In6Addr{255, 255, 0, 0}), Subnet6(addr6Full, 16).network());
105 EXPECT_EQ((In6Addr{255, 254, 0, 0}), Subnet6(addr6Full, 15).network());
106 EXPECT_EQ((In6Addr{}), Subnet6(addr6Full, 0).network());
107 EXPECT_EQ((In6Addr{}), Subnet6(In6Addr{}, 0).network());
108}
109
110TEST(Subnet6, Contains)
111{
112 auto addr6NFull = addr6Full;
113 addr6NFull.s6_addr[15] = 254;
114 EXPECT_TRUE(Subnet6(addr6Full, 128).contains(addr6Full));
115 EXPECT_FALSE(Subnet6(addr6Full, 128).contains(addr6NFull));
116 EXPECT_FALSE(Subnet6(addr6Full, 128).contains(In6Addr{}));
117 EXPECT_TRUE(
118 Subnet6(addr6Full, 127).contains(static_cast<in6_addr>(addr6Full)));
119 EXPECT_TRUE(Subnet6(addr6Full, 127).contains(addr6NFull));
120 EXPECT_TRUE(
121 Subnet6(addr6Full, 33).contains(In6Addr{255, 255, 255, 255, 128, 255}));
122 EXPECT_FALSE(
123 Subnet6(addr6Full, 33).contains(In6Addr{255, 255, 255, 255, 127}));
124 EXPECT_TRUE(Subnet6(In6Addr{}, 33).contains(In6Addr{0, 0, 0, 0, 127}));
125 EXPECT_TRUE(
126 Subnet6(addr6Full, 14).contains(In6Addr{255, 255, 0, 0, 0, 0, 0, 145}));
127 EXPECT_FALSE(Subnet6(addr6Full, 14).contains(In6Addr{255, 127, 1}));
128 EXPECT_TRUE(Subnet6(addr6Full, 0).contains(addr6Full));
129 EXPECT_TRUE(Subnet6(In6Addr{}, 0).contains(addr6Full));
130 EXPECT_TRUE(Subnet6(addr6Full, 0).contains(In6Addr{}));
131}
132
William A. Kennington III160e3822023-06-16 17:09:43 -0700133TEST(Subnet6, FromStr)
134{
135 constexpr FromStr<Subnet6> fs;
136 EXPECT_THROW(fs("10"sv), std::invalid_argument);
137 EXPECT_THROW(fs("/10"sv), std::invalid_argument);
138 EXPECT_THROW(fs("ff::"sv), std::invalid_argument);
139 EXPECT_THROW(fs("::/"sv), std::invalid_argument);
140 EXPECT_THROW(fs("0.0.0.0/0"sv), std::invalid_argument);
141 EXPECT_EQ((Subnet6{in6_addr{}, 80}), fs("::/80"sv));
William A. Kennington III39011c82023-06-28 17:49:30 -0700142 EXPECT_EQ((Subnet6{in6_addr{}, 80}), "::/80"_sub6);
William A. Kennington III160e3822023-06-16 17:09:43 -0700143}
144
William A. Kennington IIId5957f52023-06-16 16:55:01 -0700145TEST(Subnet6, ToStr)
146{
147 ToStrHandle<ToStr<Subnet6>> tsh;
148 EXPECT_EQ("::/0", tsh(Subnet6({}, 0)));
149 EXPECT_EQ("ff00::/128", tsh(Subnet6(In6Addr{0xff}, 128)));
150 EXPECT_EQ("a 102:304::/32 b",
151 fmt::format("a {} b", Subnet6(In6Addr{1, 2, 3, 4}, 32)));
William A. Kennington III5b20b0a2023-07-18 13:38:37 -0700152 EXPECT_EQ("a 102:304::/32 b",
153 std::format("a {} b", Subnet6(In6Addr{1, 2, 3, 4}, 32)));
William A. Kennington IIId5957f52023-06-16 16:55:01 -0700154}
155
William A. Kennington III14dd4eb2023-01-12 10:51:12 -0800156TEST(SubnetAny, Basic)
157{
158 EXPECT_NO_THROW(SubnetAny(in_addr{0xffffffff}, 32));
159 EXPECT_NO_THROW(SubnetAny(addr4Full, 0));
160 EXPECT_NO_THROW(SubnetAny(InAnyAddr{addr4Full}, 0));
161 EXPECT_NO_THROW(SubnetAny(in_addr{}, 10));
162 EXPECT_THROW(SubnetAny(in_addr{0xffffffff}, 33), std::invalid_argument);
163 EXPECT_THROW(SubnetAny(InAnyAddr{in_addr{0xffffffff}}, 33),
164 std::invalid_argument);
165 EXPECT_THROW(SubnetAny(in_addr{0xffffffff}, 64), std::invalid_argument);
166 EXPECT_NO_THROW(SubnetAny(in6_addr{0xff}, 128));
167 EXPECT_NO_THROW(SubnetAny(addr6Full, 0));
168 EXPECT_NO_THROW(SubnetAny(InAnyAddr{addr6Full}, 0));
169 EXPECT_NO_THROW(SubnetAny(in6_addr{}, 65));
170 EXPECT_THROW(SubnetAny(in6_addr{0xff}, 129), std::invalid_argument);
171 EXPECT_THROW(SubnetAny(InAnyAddr{in6_addr{0xff}}, 129),
172 std::invalid_argument);
173 EXPECT_THROW(SubnetAny(in6_addr{0xff}, 150), std::invalid_argument);
174
175 EXPECT_NO_THROW(SubnetAny(Subnet4(in_addr{}, 32)));
176 EXPECT_NO_THROW(SubnetAny(Subnet6(in6_addr{0xff}, 128)));
177
178 EXPECT_NE(SubnetAny(in6_addr{0xff}, 32), Subnet6(in6_addr{}, 32));
179 EXPECT_NE(Subnet6(in6_addr{0xff}, 26), SubnetAny(in6_addr{0xff}, 27));
180 EXPECT_EQ(SubnetAny(in6_addr{0xff}, 32), Subnet6(in6_addr{0xff}, 32));
181 EXPECT_EQ(SubnetAny(in6_addr{0xff}, 32), SubnetAny(in6_addr{0xff}, 32));
182 EXPECT_NE(SubnetAny(in6_addr{0xff}, 32), Subnet4(in_addr{0xff}, 32));
183 EXPECT_NE(SubnetAny(in_addr{0xff}, 32), Subnet4(in_addr{}, 32));
184 EXPECT_NE(Subnet4(in_addr{0xff}, 26), SubnetAny(in_addr{0xff}, 27));
185 EXPECT_EQ(SubnetAny(in_addr{0xff}, 32), Subnet4(in_addr{0xff}, 32));
186 EXPECT_EQ(SubnetAny(in_addr{0xff}, 32), SubnetAny(in_addr{0xff}, 32));
187}
188
189TEST(SubnetAny, Network)
190{
191 EXPECT_EQ(In6Addr(), SubnetAny(In6Addr(), 128).network());
192 EXPECT_EQ(addr6Full, SubnetAny(addr6Full, 128).network());
193 EXPECT_EQ(In6Addr(), SubnetAny(addr6Full, 0).network());
194 EXPECT_EQ(In4Addr(), SubnetAny(In4Addr(), 32).network());
195 EXPECT_EQ(addr4Full, SubnetAny(addr4Full, 32).network());
196 EXPECT_EQ(In4Addr(), SubnetAny(addr4Full, 0).network());
197}
198
199TEST(SubnetAny, Contains)
200{
201 EXPECT_TRUE(SubnetAny(addr6Full, 128).contains(addr6Full));
202 EXPECT_TRUE(SubnetAny(addr6Full, 128).contains(InAnyAddr{addr6Full}));
203 EXPECT_FALSE(SubnetAny(addr6Full, 128).contains(in6_addr{}));
204 EXPECT_FALSE(SubnetAny(addr6Full, 128).contains(InAnyAddr(in6_addr{})));
205 EXPECT_TRUE(SubnetAny(addr4Full, 32).contains(addr4Full));
206 EXPECT_TRUE(SubnetAny(addr4Full, 32).contains(InAnyAddr{addr4Full}));
207 EXPECT_FALSE(SubnetAny(addr4Full, 32).contains(in_addr{}));
208 EXPECT_FALSE(SubnetAny(addr4Full, 32).contains(InAnyAddr{In4Addr{}}));
209}
210
William A. Kennington III160e3822023-06-16 17:09:43 -0700211TEST(SubnetAny, FromStr)
212{
213 constexpr FromStr<SubnetAny> fs;
214 EXPECT_THROW(fs("10"sv), std::invalid_argument);
215 EXPECT_THROW(fs("/10"sv), std::invalid_argument);
216 EXPECT_THROW(fs("0.0.0.0"sv), std::invalid_argument);
217 EXPECT_THROW(fs("0.0.0.0/"sv), std::invalid_argument);
218 EXPECT_EQ((SubnetAny{in_addr{}, 0}), fs("0.0.0.0/0"sv));
219 EXPECT_EQ((SubnetAny{in_addr{}, 30}), fs("0.0.0.0/30"sv));
William A. Kennington III39011c82023-06-28 17:49:30 -0700220 EXPECT_EQ((SubnetAny{in_addr{}, 30}), "0.0.0.0/30"_sub);
William A. Kennington III160e3822023-06-16 17:09:43 -0700221 EXPECT_EQ((SubnetAny{in6_addr{}, 80}), fs("::/80"sv));
William A. Kennington III39011c82023-06-28 17:49:30 -0700222 EXPECT_EQ((SubnetAny{in6_addr{}, 80}), "::/80"_sub);
William A. Kennington III160e3822023-06-16 17:09:43 -0700223}
224
William A. Kennington IIId5957f52023-06-16 16:55:01 -0700225TEST(SubnetAny, ToStr)
226{
227 ToStrHandle<ToStr<SubnetAny>> tsh;
228 EXPECT_EQ("0.0.0.0/16", tsh(SubnetAny(In4Addr{}, 16)));
229 EXPECT_EQ("ff00::/128", tsh(SubnetAny(In6Addr{0xff}, 128)));
230 EXPECT_EQ("a 102:304::/32 b",
231 fmt::format("a {} b", SubnetAny(In6Addr{1, 2, 3, 4}, 32)));
William A. Kennington III5b20b0a2023-07-18 13:38:37 -0700232 EXPECT_EQ("a 102:304::/32 b",
233 std::format("a {} b", SubnetAny(In6Addr{1, 2, 3, 4}, 32)));
William A. Kennington IIId5957f52023-06-16 16:55:01 -0700234 EXPECT_EQ("a 1.2.3.4/32 b",
235 fmt::format("a {} b", SubnetAny(In4Addr{1, 2, 3, 4}, 32)));
William A. Kennington III5b20b0a2023-07-18 13:38:37 -0700236 EXPECT_EQ("a 1.2.3.4/32 b",
237 std::format("a {} b", SubnetAny(In4Addr{1, 2, 3, 4}, 32)));
William A. Kennington IIId5957f52023-06-16 16:55:01 -0700238}
239
William A. Kennington IIIc870ac32023-06-17 17:13:45 -0700240TEST(Ops, MaskToPfx)
241{
242 EXPECT_EQ(32, maskToPfx(In4Addr{0xff, 0xff, 0xff, 0xff}));
243 EXPECT_EQ(28, maskToPfx(In4Addr{0xff, 0xff, 0xff, 0xf0}));
244 EXPECT_EQ(16, maskToPfx(In4Addr{0xff, 0xff, 0, 0}));
245 EXPECT_EQ(0, maskToPfx(In4Addr{}));
246
247 EXPECT_THROW(maskToPfx(In4Addr{0, 0x8}), std::invalid_argument);
248 EXPECT_THROW(maskToPfx(In4Addr{0x40}), std::invalid_argument);
249}
250
William A. Kennington III14dd4eb2023-01-12 10:51:12 -0800251} // namespace stdplus