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