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