blob: d335adc27312c0fc7138051546827a9496ec239e [file] [log] [blame]
Ratan Gupta594123d2017-05-16 22:48:35 +05301#include "util.hpp"
2
William A. Kennington III5058f572019-01-30 17:18:14 -08003#include <arpa/inet.h>
Gunnar Mills57d9c502018-09-14 14:42:34 -05004#include <netinet/in.h>
5
William A. Kennington IIId27410f2019-01-30 17:15:43 -08006#include <cstddef>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07007#include <cstring>
William A. Kennington III12beaad2020-06-13 19:30:41 -07008#include <stdplus/raw.hpp>
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -07009#include <string>
10#include <string_view>
Ratan Gupta35297172018-11-28 18:40:16 +053011#include <xyz/openbmc_project/Common/error.hpp>
12
Lei YU307554e2021-03-18 14:56:50 +080013#include <gmock/gmock.h>
Gunnar Mills57d9c502018-09-14 14:42:34 -050014#include <gtest/gtest.h>
15
Ratan Gupta594123d2017-05-16 22:48:35 +053016namespace phosphor
17{
18namespace network
19{
20
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -070021using namespace std::literals;
Ratan Gupta35297172018-11-28 18:40:16 +053022using InternalFailure =
23 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Ratan Gupta594123d2017-05-16 22:48:35 +053024class TestUtil : public testing::Test
25{
Gunnar Mills57d9c502018-09-14 14:42:34 -050026 public:
27 TestUtil()
28 {
29 // Empty
30 }
Ratan Gupta594123d2017-05-16 22:48:35 +053031};
32
William A. Kennington IIIa00b1c32019-02-01 18:57:17 -080033TEST_F(TestUtil, AddrFromBuf)
34{
35 std::string tooSmall(1, 'a');
36 std::string tooLarge(24, 'a');
37
38 struct in_addr ip1;
39 EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
40 std::string_view buf1(reinterpret_cast<char*>(&ip1), sizeof(ip1));
41 InAddrAny res1 = addrFromBuf(AF_INET, buf1);
42 EXPECT_EQ(0, memcmp(&ip1, &std::get<struct in_addr>(res1), sizeof(ip1)));
43 EXPECT_THROW(addrFromBuf(AF_INET, tooSmall), std::runtime_error);
44 EXPECT_THROW(addrFromBuf(AF_INET, tooLarge), std::runtime_error);
45 EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf1), std::runtime_error);
46
47 struct in6_addr ip2;
48 EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
49 std::string_view buf2(reinterpret_cast<char*>(&ip2), sizeof(ip2));
50 InAddrAny res2 = addrFromBuf(AF_INET6, buf2);
51 EXPECT_EQ(0, memcmp(&ip2, &std::get<struct in6_addr>(res2), sizeof(ip2)));
52 EXPECT_THROW(addrFromBuf(AF_INET6, tooSmall), std::runtime_error);
53 EXPECT_THROW(addrFromBuf(AF_INET6, tooLarge), std::runtime_error);
54 EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf2), std::runtime_error);
55}
56
William A. Kennington III5058f572019-01-30 17:18:14 -080057TEST_F(TestUtil, IpToString)
58{
59 struct in_addr ip1;
60 EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
Alexander Filippov983da552021-02-08 15:26:54 +030061 EXPECT_EQ("192.168.10.1", toString(ip1));
William A. Kennington III5058f572019-01-30 17:18:14 -080062 EXPECT_EQ("192.168.10.1", toString(InAddrAny(ip1)));
63
64 struct in6_addr ip2;
65 EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
Alexander Filippov983da552021-02-08 15:26:54 +030066 EXPECT_EQ("fdd8:b5ad:9d93:94ee::2:1", toString(ip2));
William A. Kennington III5058f572019-01-30 17:18:14 -080067 EXPECT_EQ("fdd8:b5ad:9d93:94ee::2:1", toString(InAddrAny(ip2)));
William A. Kennington III5058f572019-01-30 17:18:14 -080068}
69
Nagaraju Goruganti067ca2d2018-01-17 01:12:00 -060070TEST_F(TestUtil, IpValidation)
71{
72 std::string ipaddress = "0.0.0.0";
73 EXPECT_EQ(true, isValidIP(AF_INET, ipaddress));
74
75 ipaddress = "9.3.185.83";
76 EXPECT_EQ(true, isValidIP(AF_INET, ipaddress));
77
78 ipaddress = "9.3.185.a";
79 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress));
80
81 ipaddress = "9.3.a.83";
82 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress));
83
84 ipaddress = "x.x.x.x";
85 EXPECT_EQ(false, isValidIP(AF_INET, ipaddress));
86
87 ipaddress = "0:0:0:0:0:0:0:0";
88 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
89
90 ipaddress = "1:0:0:0:0:0:0:8";
91 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
92
93 ipaddress = "1::8";
94 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
95
96 ipaddress = "0:0:0:0:0:FFFF:204.152.189.116";
97 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
98
99 ipaddress = "::ffff:204.152.189.116";
100 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
101
102 ipaddress = "a:0:0:0:0:FFFF:204.152.189.116";
103 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
104
105 ipaddress = "1::8";
106 EXPECT_EQ(true, isValidIP(AF_INET6, ipaddress));
Nagaraju Goruganti067ca2d2018-01-17 01:12:00 -0600107}
108
109TEST_F(TestUtil, PrefixValidation)
110{
111 uint8_t prefixLength = 1;
112 EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength));
113
114 prefixLength = 32;
115 EXPECT_EQ(true, isValidPrefix(AF_INET, prefixLength));
116
117 prefixLength = 0;
118 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
119
120 prefixLength = 33;
121 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
122
123 prefixLength = 33;
124 EXPECT_EQ(true, isValidPrefix(AF_INET6, prefixLength));
125
126 prefixLength = 65;
127 EXPECT_EQ(false, isValidPrefix(AF_INET, prefixLength));
Nagaraju Goruganti067ca2d2018-01-17 01:12:00 -0600128}
129
Ratan Gupta594123d2017-05-16 22:48:35 +0530130TEST_F(TestUtil, ConvertV4MasktoPrefix)
131{
132 std::string mask = "255.255.255.0";
133 uint8_t prefix = toCidr(AF_INET, mask);
134 EXPECT_EQ(prefix, 24);
135
William A. Kennington IIIa1b897e2021-03-31 13:27:11 -0700136 mask = "255.255.255.255";
137 prefix = toCidr(AF_INET, mask);
138 EXPECT_EQ(prefix, 32);
139
Ratan Gupta594123d2017-05-16 22:48:35 +0530140 mask = "255.255.0.0";
141 prefix = toCidr(AF_INET, mask);
142 EXPECT_EQ(prefix, 16);
143
144 mask = "255.0.0.0";
145 prefix = toCidr(AF_INET, mask);
146 EXPECT_EQ(prefix, 8);
147
148 mask = "255.224.0.0";
149 prefix = toCidr(AF_INET, mask);
150 EXPECT_EQ(prefix, 11);
151
Gunnar Mills57d9c502018-09-14 14:42:34 -0500152 // Invalid Mask
Ratan Gupta594123d2017-05-16 22:48:35 +0530153 mask = "255.0.255.0";
154 prefix = toCidr(AF_INET, mask);
155 EXPECT_EQ(prefix, 0);
156}
157
158TEST_F(TestUtil, convertV6MasktoPrefix)
159{
160 std::string mask = "ffff:ffff::";
161 uint8_t prefix = toCidr(AF_INET6, mask);
162 EXPECT_EQ(prefix, 32);
163
William A. Kennington IIIa1b897e2021-03-31 13:27:11 -0700164 mask = "::";
165 prefix = toCidr(AF_INET6, mask);
166 EXPECT_EQ(prefix, 0);
167
Ratan Gupta594123d2017-05-16 22:48:35 +0530168 mask = "ffff:ffff:ffff::";
169 prefix = toCidr(AF_INET6, mask);
170 EXPECT_EQ(prefix, 48);
171
172 mask = "ffff:ffff:fc00::";
173 prefix = toCidr(AF_INET6, mask);
174 EXPECT_EQ(prefix, 38);
175
Johnathan Mantey359623e2021-01-26 15:02:54 -0800176 mask = "ffff:0:0:0:0:0:0:0";
177 prefix = toCidr(AF_INET6, mask);
178 EXPECT_EQ(prefix, 16);
179
180 mask = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
181 prefix = toCidr(AF_INET6, mask);
182 EXPECT_EQ(prefix, 128);
183
184 mask = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc";
185 prefix = toCidr(AF_INET6, mask);
186 EXPECT_EQ(prefix, 126);
187
Lei YUa3b14dc2021-04-06 11:42:10 +0800188 mask = "ffff:ffff:ffff:ffff::";
189 prefix = toCidr(AF_INET6, mask);
190 EXPECT_EQ(prefix, 64);
191
Johnathan Mantey359623e2021-01-26 15:02:54 -0800192 // Invalid Masks
Ratan Gupta594123d2017-05-16 22:48:35 +0530193 mask = "ffff:0fff::";
194 prefix = toCidr(AF_INET6, mask);
195 EXPECT_EQ(prefix, 0);
Johnathan Mantey359623e2021-01-26 15:02:54 -0800196
197 mask = "ffff:fgff::";
198 prefix = toCidr(AF_INET6, mask);
199 EXPECT_EQ(prefix, 0);
200
201 mask = "ffff:0:0:6:0:0:0:0";
202 prefix = toCidr(AF_INET6, mask);
203 EXPECT_EQ(prefix, 0);
204
Johnathan Mantey359623e2021-01-26 15:02:54 -0800205 mask = ":";
206 prefix = toCidr(AF_INET6, mask);
207 EXPECT_EQ(prefix, 0);
208
209 mask = "abcd:efgh:ijkl:mnop:pqrs:tuvw:xyz:abcd";
210 prefix = toCidr(AF_INET6, mask);
211 EXPECT_EQ(prefix, 0);
212
213 mask = "ffff:0:0:0:0:0:0";
214 prefix = toCidr(AF_INET6, mask);
215 EXPECT_EQ(prefix, 0);
Ratan Gupta594123d2017-05-16 22:48:35 +0530216}
217
Ratan Gupta11cef802017-05-29 08:41:48 +0530218TEST_F(TestUtil, isLinkLocaladdress)
Ratan Gupta594123d2017-05-16 22:48:35 +0530219{
220 std::string ipaddress = "fe80:fec0::";
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500221 EXPECT_TRUE(isLinkLocalIP(ipaddress));
Ratan Gupta594123d2017-05-16 22:48:35 +0530222
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500223 ipaddress = "2000:fe80:789::";
224 EXPECT_FALSE(isLinkLocalIP(ipaddress));
Ratan Gupta594123d2017-05-16 22:48:35 +0530225
226 ipaddress = "2000:fe80::";
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500227 EXPECT_FALSE(isLinkLocalIP(ipaddress));
228
229 ipaddress = "169.254.3.3";
230 EXPECT_TRUE(isLinkLocalIP(ipaddress));
231
232 ipaddress = "3.169.254.3";
233 EXPECT_FALSE(isLinkLocalIP(ipaddress));
234
235 ipaddress = "3.3.169.254";
236 EXPECT_FALSE(isLinkLocalIP(ipaddress));
Ratan Gupta594123d2017-05-16 22:48:35 +0530237}
238
239TEST_F(TestUtil, convertPrefixToMask)
240{
241 std::string mask = toMask(AF_INET, 24);
242 EXPECT_EQ(mask, "255.255.255.0");
243
244 mask = toMask(AF_INET, 8);
245 EXPECT_EQ(mask, "255.0.0.0");
246
247 mask = toMask(AF_INET, 27);
248 EXPECT_EQ(mask, "255.255.255.224");
249}
250
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700251TEST_F(TestUtil, InterfaceToUbootEthAddr)
252{
253 EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("et"));
254 EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth"));
255 EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("sit0"));
256 EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("ethh0"));
257 EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth0h"));
258 EXPECT_EQ("ethaddr", interfaceToUbootEthAddr("eth0"));
259 EXPECT_EQ("eth1addr", interfaceToUbootEthAddr("eth1"));
260 EXPECT_EQ("eth5addr", interfaceToUbootEthAddr("eth5"));
261 EXPECT_EQ("eth28addr", interfaceToUbootEthAddr("eth28"));
262}
263
William A. Kennington III1137a972019-04-20 20:49:58 -0700264namespace mac_address
265{
266
267TEST(MacFromString, Bad)
268{
Asmitha Karunanithi86f659e2021-01-05 00:16:03 -0600269 EXPECT_THROW(fromString("0x:00:00:00:00:00"), std::invalid_argument);
270 EXPECT_THROW(fromString("00:00:00:00:00"), std::invalid_argument);
271 EXPECT_THROW(fromString(""), std::invalid_argument);
William A. Kennington III1137a972019-04-20 20:49:58 -0700272}
273
274TEST(MacFromString, Valid)
275{
William A. Kennington III12beaad2020-06-13 19:30:41 -0700276 EXPECT_TRUE(
277 stdplus::raw::equal(ether_addr{}, fromString("00:00:00:00:00:00")));
278 EXPECT_TRUE(
279 stdplus::raw::equal(ether_addr{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa},
280 fromString("FF:EE:DD:cc:bb:aa")));
281 EXPECT_TRUE(
282 stdplus::raw::equal(ether_addr{0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
283 fromString("0:1:2:3:4:5")));
William A. Kennington III1137a972019-04-20 20:49:58 -0700284}
285
286TEST(MacToString, Valid)
287{
288 EXPECT_EQ("11:22:33:44:55:66",
289 toString({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}));
Karthick Sundarrajandbd328d2019-11-20 15:19:08 -0800290 EXPECT_EQ("01:02:03:04:05:67",
291 toString({0x01, 0x02, 0x03, 0x04, 0x05, 0x67}));
292 EXPECT_EQ("00:00:00:00:00:00",
293 toString({0x00, 0x00, 0x00, 0x00, 0x00, 0x00}));
William A. Kennington III1137a972019-04-20 20:49:58 -0700294}
295
296TEST(MacIsEmpty, True)
297{
298 EXPECT_TRUE(isEmpty({}));
299}
300
301TEST(MacIsEmpty, False)
302{
303 EXPECT_FALSE(isEmpty(fromString("01:00:00:00:00:00")));
304 EXPECT_FALSE(isEmpty(fromString("00:00:00:10:00:00")));
305 EXPECT_FALSE(isEmpty(fromString("00:00:00:00:00:01")));
306}
307
308TEST(MacIsMulticast, True)
309{
310 EXPECT_TRUE(isMulticast(fromString("ff:ff:ff:ff:ff:ff")));
311 EXPECT_TRUE(isMulticast(fromString("01:00:00:00:00:00")));
312}
313
314TEST(MacIsMulticast, False)
315{
316 EXPECT_FALSE(isMulticast(fromString("00:11:22:33:44:55")));
317 EXPECT_FALSE(isMulticast(fromString("FE:11:22:33:44:55")));
318}
319
320TEST(MacIsUnicast, True)
321{
322 EXPECT_TRUE(isUnicast(fromString("00:11:22:33:44:55")));
323 EXPECT_TRUE(isUnicast(fromString("FE:11:22:33:44:55")));
324}
325
326TEST(MacIsUnicast, False)
327{
328 EXPECT_FALSE(isUnicast(fromString("00:00:00:00:00:00")));
329 EXPECT_FALSE(isUnicast(fromString("01:00:00:00:00:00")));
330 EXPECT_FALSE(isUnicast(fromString("ff:ff:ff:ff:ff:ff")));
331}
332
Lei YU307554e2021-03-18 14:56:50 +0800333TEST(IgnoredInterfaces, Empty)
334{
335 auto ret = internal::parseInterfaces({});
336 EXPECT_TRUE(ret.empty());
337
338 ret = internal::parseInterfaces(" , ,, ");
339 EXPECT_TRUE(ret.empty());
340}
341
342TEST(IgnoredInterfaces, NotEmpty)
343{
344 using ::testing::ContainerEq;
William A. Kennington IIIee5b2c92021-04-28 02:31:28 -0700345 std::set<std::string_view> expected = {"eth0"};
Lei YU307554e2021-03-18 14:56:50 +0800346 auto ret = internal::parseInterfaces("eth0");
347 EXPECT_THAT(ret, ContainerEq(expected));
348
349 expected = {"eth0", "eth1", "bond1", "usb0"};
350 ret = internal::parseInterfaces(" ,eth0, eth1 ,bond1, usb0,,");
351 EXPECT_THAT(ret, ContainerEq(expected));
352}
353
William A. Kennington III1137a972019-04-20 20:49:58 -0700354} // namespace mac_address
Gunnar Mills57d9c502018-09-14 14:42:34 -0500355} // namespace network
356} // namespace phosphor