1 #include "util.hpp"
2 
3 #include <arpa/inet.h>
4 #include <fmt/chrono.h>
5 #include <netinet/in.h>
6 
7 #include <cstddef>
8 #include <cstring>
9 #include <stdexcept>
10 #include <string>
11 #include <string_view>
12 #include <xyz/openbmc_project/Common/error.hpp>
13 
14 #include <gmock/gmock.h>
15 #include <gtest/gtest.h>
16 
17 namespace phosphor
18 {
19 namespace network
20 {
21 
22 using namespace std::literals;
23 using InternalFailure =
24     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
25 class TestUtil : public testing::Test
26 {
27   public:
28     TestUtil()
29     {
30         // Empty
31     }
32 };
33 
34 TEST_F(TestUtil, AddrFromBuf)
35 {
36     std::string tooSmall(1, 'a');
37     std::string tooLarge(24, 'a');
38 
39     struct in_addr ip1;
40     EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
41     std::string_view buf1(reinterpret_cast<char*>(&ip1), sizeof(ip1));
42     InAddrAny res1 = addrFromBuf(AF_INET, buf1);
43     EXPECT_EQ(0, memcmp(&ip1, &std::get<struct in_addr>(res1), sizeof(ip1)));
44     EXPECT_THROW(addrFromBuf(AF_INET, tooSmall), std::runtime_error);
45     EXPECT_THROW(addrFromBuf(AF_INET, tooLarge), std::runtime_error);
46     EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf1), std::invalid_argument);
47 
48     struct in6_addr ip2;
49     EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
50     std::string_view buf2(reinterpret_cast<char*>(&ip2), sizeof(ip2));
51     InAddrAny res2 = addrFromBuf(AF_INET6, buf2);
52     EXPECT_EQ(0, memcmp(&ip2, &std::get<struct in6_addr>(res2), sizeof(ip2)));
53     EXPECT_THROW(addrFromBuf(AF_INET6, tooSmall), std::runtime_error);
54     EXPECT_THROW(addrFromBuf(AF_INET6, tooLarge), std::runtime_error);
55     EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf2), std::invalid_argument);
56 }
57 
58 TEST_F(TestUtil, InterfaceToUbootEthAddr)
59 {
60     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("et"));
61     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth"));
62     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("sit0"));
63     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("ethh0"));
64     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth0h"));
65     EXPECT_EQ("ethaddr", interfaceToUbootEthAddr("eth0"));
66     EXPECT_EQ("eth1addr", interfaceToUbootEthAddr("eth1"));
67     EXPECT_EQ("eth5addr", interfaceToUbootEthAddr("eth5"));
68     EXPECT_EQ("eth28addr", interfaceToUbootEthAddr("eth28"));
69 }
70 
71 namespace mac_address
72 {
73 
74 TEST(MacIsEmpty, True)
75 {
76     EXPECT_TRUE(isEmpty({}));
77 }
78 
79 TEST(MacIsEmpty, False)
80 {
81     EXPECT_FALSE(isEmpty({1}));
82     EXPECT_FALSE(isEmpty({0, 0, 0, 1}));
83     EXPECT_FALSE(isEmpty({0, 0, 0, 0, 0, 1}));
84 }
85 
86 TEST(MacIsMulticast, True)
87 {
88     EXPECT_TRUE(isMulticast({255, 255, 255, 255, 255, 255}));
89     EXPECT_TRUE(isMulticast({1}));
90 }
91 
92 TEST(MacIsMulticast, False)
93 {
94     EXPECT_FALSE(isMulticast({0, 1, 2, 3, 4, 5}));
95     EXPECT_FALSE(isMulticast({0xfe, 255, 255, 255, 255, 255}));
96 }
97 
98 TEST(MacIsUnicast, True)
99 {
100     EXPECT_TRUE(isUnicast({0, 1, 2, 3, 4, 5}));
101     EXPECT_TRUE(isUnicast({0xfe, 255, 255, 255, 255, 255}));
102 }
103 
104 TEST(MacIsUnicast, False)
105 {
106     EXPECT_FALSE(isUnicast({}));
107     EXPECT_FALSE(isUnicast({1}));
108     EXPECT_FALSE(isUnicast({255, 255, 255, 255, 255, 255}));
109 }
110 
111 TEST(IgnoredInterfaces, Empty)
112 {
113     auto ret = internal::parseInterfaces({});
114     EXPECT_TRUE(ret.empty());
115 
116     ret = internal::parseInterfaces(" ,  ,, ");
117     EXPECT_TRUE(ret.empty());
118 }
119 
120 TEST(IgnoredInterfaces, NotEmpty)
121 {
122     using ::testing::ContainerEq;
123     std::unordered_set<std::string_view> expected = {"eth0"};
124     auto ret = internal::parseInterfaces("eth0");
125     EXPECT_THAT(ret, ContainerEq(expected));
126 
127     expected = {"eth0", "eth1", "bond1", "usb0"};
128     ret = internal::parseInterfaces(" ,eth0, eth1  ,bond1, usb0,,");
129     EXPECT_THAT(ret, ContainerEq(expected));
130 }
131 
132 } // namespace mac_address
133 } // namespace network
134 } // namespace phosphor
135