xref: /openbmc/phosphor-networkd/test/test_util.cpp (revision b01d08fd6607411d4f032b4ddf610f455bbafb86)
1 #include "util.hpp"
2 
3 #include <arpa/inet.h>
4 #include <fmt/chrono.h>
5 #include <netinet/in.h>
6 
7 #include <charconv>
8 #include <cstddef>
9 #include <cstring>
10 #include <stdexcept>
11 #include <string>
12 #include <string_view>
13 #include <xyz/openbmc_project/Common/error.hpp>
14 
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 namespace phosphor
19 {
20 namespace network
21 {
22 
23 using namespace std::literals;
24 using InternalFailure =
25     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
26 class TestUtil : public testing::Test
27 {
28   public:
29     TestUtil()
30     {
31         // Empty
32     }
33 };
34 
35 TEST_F(TestUtil, AddrFromBuf)
36 {
37     std::string tooSmall(1, 'a');
38     std::string tooLarge(24, 'a');
39 
40     struct in_addr ip1;
41     EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
42     std::string_view buf1(reinterpret_cast<char*>(&ip1), sizeof(ip1));
43     InAddrAny res1 = addrFromBuf(AF_INET, buf1);
44     EXPECT_EQ(0, memcmp(&ip1, &std::get<struct in_addr>(res1), sizeof(ip1)));
45     EXPECT_THROW(addrFromBuf(AF_INET, tooSmall), std::runtime_error);
46     EXPECT_THROW(addrFromBuf(AF_INET, tooLarge), std::runtime_error);
47     EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf1), std::invalid_argument);
48 
49     struct in6_addr ip2;
50     EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
51     std::string_view buf2(reinterpret_cast<char*>(&ip2), sizeof(ip2));
52     InAddrAny res2 = addrFromBuf(AF_INET6, buf2);
53     EXPECT_EQ(0, memcmp(&ip2, &std::get<struct in6_addr>(res2), sizeof(ip2)));
54     EXPECT_THROW(addrFromBuf(AF_INET6, tooSmall), std::runtime_error);
55     EXPECT_THROW(addrFromBuf(AF_INET6, tooLarge), std::runtime_error);
56     EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf2), std::invalid_argument);
57 }
58 
59 TEST_F(TestUtil, IpValidation)
60 {
61     EXPECT_TRUE(isValidIP(AF_INET, "0.0.0.0"));
62     EXPECT_TRUE(isValidIP("0.0.0.0"));
63 
64     EXPECT_TRUE(isValidIP(AF_INET, "9.3.185.83"));
65 
66     EXPECT_FALSE(isValidIP(AF_INET, "9.3.185.a"));
67     EXPECT_FALSE(isValidIP("9.3.185.a"));
68 
69     EXPECT_FALSE(isValidIP(AF_INET, "9.3.a.83"));
70 
71     EXPECT_FALSE(isValidIP(AF_INET, "x.x.x.x"));
72 
73     EXPECT_TRUE(isValidIP(AF_INET6, "0:0:0:0:0:0:0:0"));
74     EXPECT_TRUE(isValidIP("0:0:0:0:0:0:0:0"));
75 
76     EXPECT_TRUE(isValidIP(AF_INET6, "1:0:0:0:0:0:0:8"));
77 
78     EXPECT_TRUE(isValidIP(AF_INET6, "1::8"));
79 
80     EXPECT_TRUE(isValidIP(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116"));
81 
82     EXPECT_TRUE(isValidIP(AF_INET6, "::ffff:204.152.189.116"));
83 
84     EXPECT_TRUE(isValidIP(AF_INET6, "a:0:0:0:0:FFFF:204.152.189.116"));
85 
86     EXPECT_TRUE(isValidIP(AF_INET6, "1::8"));
87 }
88 
89 TEST_F(TestUtil, PrefixValidation)
90 {
91     EXPECT_TRUE(isValidPrefix(AF_INET, 0));
92     EXPECT_TRUE(isValidPrefix(AF_INET, 1));
93     EXPECT_TRUE(isValidPrefix(AF_INET, 32));
94     EXPECT_FALSE(isValidPrefix(AF_INET, 33));
95     EXPECT_FALSE(isValidPrefix(AF_INET, 64));
96 
97     EXPECT_TRUE(isValidPrefix(AF_INET6, 0));
98     EXPECT_TRUE(isValidPrefix(AF_INET6, 1));
99     EXPECT_TRUE(isValidPrefix(AF_INET6, 53));
100     EXPECT_TRUE(isValidPrefix(AF_INET6, 64));
101     EXPECT_TRUE(isValidPrefix(AF_INET6, 128));
102     EXPECT_FALSE(isValidPrefix(AF_INET6, 129));
103     EXPECT_FALSE(isValidPrefix(AF_INET6, 177));
104 
105     EXPECT_THROW(isValidPrefix(AF_UNSPEC, 1), std::invalid_argument);
106 }
107 
108 TEST_F(TestUtil, InterfaceToUbootEthAddr)
109 {
110     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("et"));
111     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth"));
112     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("sit0"));
113     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("ethh0"));
114     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth0h"));
115     EXPECT_EQ("ethaddr", interfaceToUbootEthAddr("eth0"));
116     EXPECT_EQ("eth1addr", interfaceToUbootEthAddr("eth1"));
117     EXPECT_EQ("eth5addr", interfaceToUbootEthAddr("eth5"));
118     EXPECT_EQ("eth28addr", interfaceToUbootEthAddr("eth28"));
119 }
120 
121 namespace mac_address
122 {
123 
124 TEST(MacIsEmpty, True)
125 {
126     EXPECT_TRUE(isEmpty({}));
127 }
128 
129 TEST(MacIsEmpty, False)
130 {
131     EXPECT_FALSE(isEmpty({1}));
132     EXPECT_FALSE(isEmpty({0, 0, 0, 1}));
133     EXPECT_FALSE(isEmpty({0, 0, 0, 0, 0, 1}));
134 }
135 
136 TEST(MacIsMulticast, True)
137 {
138     EXPECT_TRUE(isMulticast({255, 255, 255, 255, 255, 255}));
139     EXPECT_TRUE(isMulticast({1}));
140 }
141 
142 TEST(MacIsMulticast, False)
143 {
144     EXPECT_FALSE(isMulticast({0, 1, 2, 3, 4, 5}));
145     EXPECT_FALSE(isMulticast({0xfe, 255, 255, 255, 255, 255}));
146 }
147 
148 TEST(MacIsUnicast, True)
149 {
150     EXPECT_TRUE(isUnicast({0, 1, 2, 3, 4, 5}));
151     EXPECT_TRUE(isUnicast({0xfe, 255, 255, 255, 255, 255}));
152 }
153 
154 TEST(MacIsUnicast, False)
155 {
156     EXPECT_FALSE(isUnicast({}));
157     EXPECT_FALSE(isUnicast({1}));
158     EXPECT_FALSE(isUnicast({255, 255, 255, 255, 255, 255}));
159 }
160 
161 TEST(IgnoredInterfaces, Empty)
162 {
163     auto ret = internal::parseInterfaces({});
164     EXPECT_TRUE(ret.empty());
165 
166     ret = internal::parseInterfaces(" ,  ,, ");
167     EXPECT_TRUE(ret.empty());
168 }
169 
170 TEST(IgnoredInterfaces, NotEmpty)
171 {
172     using ::testing::ContainerEq;
173     std::unordered_set<std::string_view> expected = {"eth0"};
174     auto ret = internal::parseInterfaces("eth0");
175     EXPECT_THAT(ret, ContainerEq(expected));
176 
177     expected = {"eth0", "eth1", "bond1", "usb0"};
178     ret = internal::parseInterfaces(" ,eth0, eth1  ,bond1, usb0,,");
179     EXPECT_THAT(ret, ContainerEq(expected));
180 }
181 
182 } // namespace mac_address
183 } // namespace network
184 } // namespace phosphor
185