1*1bbe3d1eSWilliam A. Kennington III #pragma once 2*1bbe3d1eSWilliam A. Kennington III 3*1bbe3d1eSWilliam A. Kennington III #include "config.h" 4*1bbe3d1eSWilliam A. Kennington III 5*1bbe3d1eSWilliam A. Kennington III #include "ethernet_interface.hpp" 6*1bbe3d1eSWilliam A. Kennington III #include "types.hpp" 7*1bbe3d1eSWilliam A. Kennington III 8*1bbe3d1eSWilliam A. Kennington III #include <netinet/ether.h> 9*1bbe3d1eSWilliam A. Kennington III #include <unistd.h> 10*1bbe3d1eSWilliam A. Kennington III 11*1bbe3d1eSWilliam A. Kennington III #include <cstring> 12*1bbe3d1eSWilliam A. Kennington III #include <optional> 13*1bbe3d1eSWilliam A. Kennington III #include <sdbusplus/bus.hpp> 14*1bbe3d1eSWilliam A. Kennington III #include <string> 15*1bbe3d1eSWilliam A. Kennington III #include <string_view> 16*1bbe3d1eSWilliam A. Kennington III #include <xyz/openbmc_project/Network/EthernetInterface/server.hpp> 17*1bbe3d1eSWilliam A. Kennington III 18*1bbe3d1eSWilliam A. Kennington III namespace phosphor 19*1bbe3d1eSWilliam A. Kennington III { 20*1bbe3d1eSWilliam A. Kennington III namespace network 21*1bbe3d1eSWilliam A. Kennington III { 22*1bbe3d1eSWilliam A. Kennington III 23*1bbe3d1eSWilliam A. Kennington III using EthernetInterfaceIntf = 24*1bbe3d1eSWilliam A. Kennington III sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface; 25*1bbe3d1eSWilliam A. Kennington III 26*1bbe3d1eSWilliam A. Kennington III constexpr auto IPV4_MIN_PREFIX_LENGTH = 1; 27*1bbe3d1eSWilliam A. Kennington III constexpr auto IPV4_MAX_PREFIX_LENGTH = 32; 28*1bbe3d1eSWilliam A. Kennington III constexpr auto IPV6_MAX_PREFIX_LENGTH = 128; 29*1bbe3d1eSWilliam A. Kennington III constexpr auto IPV4_PREFIX = "169.254"; 30*1bbe3d1eSWilliam A. Kennington III constexpr auto IPV6_PREFIX = "fe80"; 31*1bbe3d1eSWilliam A. Kennington III 32*1bbe3d1eSWilliam A. Kennington III namespace mac_address 33*1bbe3d1eSWilliam A. Kennington III { 34*1bbe3d1eSWilliam A. Kennington III 35*1bbe3d1eSWilliam A. Kennington III /** @brief gets the MAC address from the Inventory. 36*1bbe3d1eSWilliam A. Kennington III * @param[in] bus - DBUS Bus Object. 37*1bbe3d1eSWilliam A. Kennington III * @param[in] intfName - Interface name 38*1bbe3d1eSWilliam A. Kennington III */ 39*1bbe3d1eSWilliam A. Kennington III ether_addr getfromInventory(sdbusplus::bus::bus& bus, 40*1bbe3d1eSWilliam A. Kennington III const std::string& intfName); 41*1bbe3d1eSWilliam A. Kennington III 42*1bbe3d1eSWilliam A. Kennington III /** @brief Converts the given mac address into byte form 43*1bbe3d1eSWilliam A. Kennington III * @param[in] str - The mac address in human readable form 44*1bbe3d1eSWilliam A. Kennington III * @returns A mac address in network byte order 45*1bbe3d1eSWilliam A. Kennington III * @throws std::runtime_error for bad mac 46*1bbe3d1eSWilliam A. Kennington III */ 47*1bbe3d1eSWilliam A. Kennington III ether_addr fromString(const char* str); 48*1bbe3d1eSWilliam A. Kennington III inline ether_addr fromString(const std::string& str) 49*1bbe3d1eSWilliam A. Kennington III { 50*1bbe3d1eSWilliam A. Kennington III return fromString(str.c_str()); 51*1bbe3d1eSWilliam A. Kennington III } 52*1bbe3d1eSWilliam A. Kennington III 53*1bbe3d1eSWilliam A. Kennington III /** @brief Converts the given mac address bytes into a string 54*1bbe3d1eSWilliam A. Kennington III * @param[in] mac - The mac address 55*1bbe3d1eSWilliam A. Kennington III * @returns A valid mac address string 56*1bbe3d1eSWilliam A. Kennington III */ 57*1bbe3d1eSWilliam A. Kennington III std::string toString(const ether_addr& mac); 58*1bbe3d1eSWilliam A. Kennington III 59*1bbe3d1eSWilliam A. Kennington III /** @brief Determines if the mac address is empty 60*1bbe3d1eSWilliam A. Kennington III * @param[in] mac - The mac address 61*1bbe3d1eSWilliam A. Kennington III * @return True if 00:00:00:00:00:00 62*1bbe3d1eSWilliam A. Kennington III */ 63*1bbe3d1eSWilliam A. Kennington III bool isEmpty(const ether_addr& mac); 64*1bbe3d1eSWilliam A. Kennington III 65*1bbe3d1eSWilliam A. Kennington III /** @brief Determines if the mac address is a multicast address 66*1bbe3d1eSWilliam A. Kennington III * @param[in] mac - The mac address 67*1bbe3d1eSWilliam A. Kennington III * @return True if multicast bit is set 68*1bbe3d1eSWilliam A. Kennington III */ 69*1bbe3d1eSWilliam A. Kennington III bool isMulticast(const ether_addr& mac); 70*1bbe3d1eSWilliam A. Kennington III 71*1bbe3d1eSWilliam A. Kennington III /** @brief Determines if the mac address is a unicast address 72*1bbe3d1eSWilliam A. Kennington III * @param[in] mac - The mac address 73*1bbe3d1eSWilliam A. Kennington III * @return True if not multicast or empty 74*1bbe3d1eSWilliam A. Kennington III */ 75*1bbe3d1eSWilliam A. Kennington III bool isUnicast(const ether_addr& mac); 76*1bbe3d1eSWilliam A. Kennington III 77*1bbe3d1eSWilliam A. Kennington III } // namespace mac_address 78*1bbe3d1eSWilliam A. Kennington III 79*1bbe3d1eSWilliam A. Kennington III constexpr auto networkdService = "systemd-networkd.service"; 80*1bbe3d1eSWilliam A. Kennington III constexpr auto timeSynchdService = "systemd-timesyncd.service"; 81*1bbe3d1eSWilliam A. Kennington III 82*1bbe3d1eSWilliam A. Kennington III /* @brief converts the given subnet into prefix notation. 83*1bbe3d1eSWilliam A. Kennington III * @param[in] addressFamily - IP address family(AF_INET/AF_INET6). 84*1bbe3d1eSWilliam A. Kennington III * @param[in] mask - Subnet Mask. 85*1bbe3d1eSWilliam A. Kennington III * @returns prefix. 86*1bbe3d1eSWilliam A. Kennington III */ 87*1bbe3d1eSWilliam A. Kennington III uint8_t toCidr(int addressFamily, const std::string& mask); 88*1bbe3d1eSWilliam A. Kennington III 89*1bbe3d1eSWilliam A. Kennington III /* @brief converts a sockaddr for the specified address family into 90*1bbe3d1eSWilliam A. Kennington III * a type_safe InAddrAny. 91*1bbe3d1eSWilliam A. Kennington III * @param[in] addressFamily - The address family of the buf 92*1bbe3d1eSWilliam A. Kennington III * @param[in] buf - The network byte order address 93*1bbe3d1eSWilliam A. Kennington III */ 94*1bbe3d1eSWilliam A. Kennington III InAddrAny addrFromBuf(int addressFamily, std::string_view buf); 95*1bbe3d1eSWilliam A. Kennington III 96*1bbe3d1eSWilliam A. Kennington III /* @brief converts the ip bytes into a string representation 97*1bbe3d1eSWilliam A. Kennington III * @param[in] addr - input ip address to convert. 98*1bbe3d1eSWilliam A. Kennington III * @returns String representation of the ip. 99*1bbe3d1eSWilliam A. Kennington III */ 100*1bbe3d1eSWilliam A. Kennington III std::string toString(const InAddrAny& addr); 101*1bbe3d1eSWilliam A. Kennington III std::string toString(const struct in_addr& addr); 102*1bbe3d1eSWilliam A. Kennington III std::string toString(const struct in6_addr& addr); 103*1bbe3d1eSWilliam A. Kennington III 104*1bbe3d1eSWilliam A. Kennington III /* @brief converts the prefix into subnetmask. 105*1bbe3d1eSWilliam A. Kennington III * @param[in] addressFamily - IP address family(AF_INET/AF_INET6). 106*1bbe3d1eSWilliam A. Kennington III * @param[in] prefix - prefix length. 107*1bbe3d1eSWilliam A. Kennington III * @returns subnet mask. 108*1bbe3d1eSWilliam A. Kennington III */ 109*1bbe3d1eSWilliam A. Kennington III std::string toMask(int addressFamily, uint8_t prefix); 110*1bbe3d1eSWilliam A. Kennington III 111*1bbe3d1eSWilliam A. Kennington III /* @brief checks that the given ip address is link local or not. 112*1bbe3d1eSWilliam A. Kennington III * @param[in] address - IP address. 113*1bbe3d1eSWilliam A. Kennington III * @returns true if it is linklocal otherwise false. 114*1bbe3d1eSWilliam A. Kennington III */ 115*1bbe3d1eSWilliam A. Kennington III bool isLinkLocalIP(const std::string& address); 116*1bbe3d1eSWilliam A. Kennington III 117*1bbe3d1eSWilliam A. Kennington III /* @brief checks that the given ip address valid or not. 118*1bbe3d1eSWilliam A. Kennington III * @param[in] addressFamily - IP address family(AF_INET/AF_INET6). 119*1bbe3d1eSWilliam A. Kennington III * @param[in] address - IP address. 120*1bbe3d1eSWilliam A. Kennington III * @returns true if it is valid otherwise false. 121*1bbe3d1eSWilliam A. Kennington III */ 122*1bbe3d1eSWilliam A. Kennington III bool isValidIP(int addressFamily, const std::string& address); 123*1bbe3d1eSWilliam A. Kennington III 124*1bbe3d1eSWilliam A. Kennington III /* @brief checks that the given prefix is valid or not. 125*1bbe3d1eSWilliam A. Kennington III * @param[in] addressFamily - IP address family(AF_INET/AF_INET6). 126*1bbe3d1eSWilliam A. Kennington III * @param[in] prefix - prefix length. 127*1bbe3d1eSWilliam A. Kennington III * @returns true if it is valid otherwise false. 128*1bbe3d1eSWilliam A. Kennington III */ 129*1bbe3d1eSWilliam A. Kennington III bool isValidPrefix(int addressFamily, uint8_t prefixLength); 130*1bbe3d1eSWilliam A. Kennington III 131*1bbe3d1eSWilliam A. Kennington III /** @brief Gets the map of interface and the associated 132*1bbe3d1eSWilliam A. Kennington III * address. 133*1bbe3d1eSWilliam A. Kennington III * @returns map of interface and the address. 134*1bbe3d1eSWilliam A. Kennington III */ 135*1bbe3d1eSWilliam A. Kennington III IntfAddrMap getInterfaceAddrs(); 136*1bbe3d1eSWilliam A. Kennington III 137*1bbe3d1eSWilliam A. Kennington III /** @brief Get all the interfaces from the system. 138*1bbe3d1eSWilliam A. Kennington III * @returns list of interface names. 139*1bbe3d1eSWilliam A. Kennington III */ 140*1bbe3d1eSWilliam A. Kennington III InterfaceList getInterfaces(); 141*1bbe3d1eSWilliam A. Kennington III 142*1bbe3d1eSWilliam A. Kennington III /** @brief Delete the given interface. 143*1bbe3d1eSWilliam A. Kennington III * @param[in] intf - interface name. 144*1bbe3d1eSWilliam A. Kennington III */ 145*1bbe3d1eSWilliam A. Kennington III void deleteInterface(const std::string& intf); 146*1bbe3d1eSWilliam A. Kennington III 147*1bbe3d1eSWilliam A. Kennington III /** @brief Converts the interface name into a u-boot environment 148*1bbe3d1eSWilliam A. Kennington III * variable that would hold its ethernet address. 149*1bbe3d1eSWilliam A. Kennington III * 150*1bbe3d1eSWilliam A. Kennington III * @param[in] intf - interface name 151*1bbe3d1eSWilliam A. Kennington III * @return The name of th environment key 152*1bbe3d1eSWilliam A. Kennington III */ 153*1bbe3d1eSWilliam A. Kennington III std::optional<std::string> interfaceToUbootEthAddr(const char* intf); 154*1bbe3d1eSWilliam A. Kennington III 155*1bbe3d1eSWilliam A. Kennington III /** @brief read the DHCP value from the configuration file 156*1bbe3d1eSWilliam A. Kennington III * @param[in] confDir - Network configuration directory. 157*1bbe3d1eSWilliam A. Kennington III * @param[in] intf - Interface name. 158*1bbe3d1eSWilliam A. Kennington III */ 159*1bbe3d1eSWilliam A. Kennington III EthernetInterfaceIntf::DHCPConf getDHCPValue(const std::string& confDir, 160*1bbe3d1eSWilliam A. Kennington III const std::string& intf); 161*1bbe3d1eSWilliam A. Kennington III 162*1bbe3d1eSWilliam A. Kennington III namespace internal 163*1bbe3d1eSWilliam A. Kennington III { 164*1bbe3d1eSWilliam A. Kennington III 165*1bbe3d1eSWilliam A. Kennington III /* @brief runs the given command in child process. 166*1bbe3d1eSWilliam A. Kennington III * @param[in] path - path of the binary file which needs to be execeuted. 167*1bbe3d1eSWilliam A. Kennington III * @param[in] args - arguments of the command. 168*1bbe3d1eSWilliam A. Kennington III */ 169*1bbe3d1eSWilliam A. Kennington III void executeCommandinChildProcess(const char* path, char** args); 170*1bbe3d1eSWilliam A. Kennington III 171*1bbe3d1eSWilliam A. Kennington III /** @brief Get ignored interfaces from environment */ 172*1bbe3d1eSWilliam A. Kennington III std::string_view getIgnoredInterfacesEnv(); 173*1bbe3d1eSWilliam A. Kennington III 174*1bbe3d1eSWilliam A. Kennington III /** @brief Parse the comma separated interface names */ 175*1bbe3d1eSWilliam A. Kennington III std::set<std::string_view> parseInterfaces(std::string_view interfaces); 176*1bbe3d1eSWilliam A. Kennington III 177*1bbe3d1eSWilliam A. Kennington III /** @brief Get the ignored interfaces */ 178*1bbe3d1eSWilliam A. Kennington III const std::set<std::string_view>& getIgnoredInterfaces(); 179*1bbe3d1eSWilliam A. Kennington III 180*1bbe3d1eSWilliam A. Kennington III } // namespace internal 181*1bbe3d1eSWilliam A. Kennington III 182*1bbe3d1eSWilliam A. Kennington III /* @brief runs the given command in child process. 183*1bbe3d1eSWilliam A. Kennington III * @param[in] path -path of the binary file which needs to be execeuted. 184*1bbe3d1eSWilliam A. Kennington III * @param[in] tArgs - arguments of the command. 185*1bbe3d1eSWilliam A. Kennington III */ 186*1bbe3d1eSWilliam A. Kennington III template <typename... ArgTypes> 187*1bbe3d1eSWilliam A. Kennington III void execute(const char* path, ArgTypes&&... tArgs) 188*1bbe3d1eSWilliam A. Kennington III { 189*1bbe3d1eSWilliam A. Kennington III using expandType = char*[]; 190*1bbe3d1eSWilliam A. Kennington III 191*1bbe3d1eSWilliam A. Kennington III expandType args = {const_cast<char*>(tArgs)..., nullptr}; 192*1bbe3d1eSWilliam A. Kennington III 193*1bbe3d1eSWilliam A. Kennington III internal::executeCommandinChildProcess(path, args); 194*1bbe3d1eSWilliam A. Kennington III } 195*1bbe3d1eSWilliam A. Kennington III 196*1bbe3d1eSWilliam A. Kennington III } // namespace network 197*1bbe3d1eSWilliam A. Kennington III 198*1bbe3d1eSWilliam A. Kennington III class Descriptor 199*1bbe3d1eSWilliam A. Kennington III { 200*1bbe3d1eSWilliam A. Kennington III private: 201*1bbe3d1eSWilliam A. Kennington III /** default value */ 202*1bbe3d1eSWilliam A. Kennington III int fd = -1; 203*1bbe3d1eSWilliam A. Kennington III 204*1bbe3d1eSWilliam A. Kennington III public: 205*1bbe3d1eSWilliam A. Kennington III Descriptor() = default; 206*1bbe3d1eSWilliam A. Kennington III Descriptor(const Descriptor&) = delete; 207*1bbe3d1eSWilliam A. Kennington III Descriptor& operator=(const Descriptor&) = delete; 208*1bbe3d1eSWilliam A. Kennington III Descriptor(Descriptor&&) = delete; 209*1bbe3d1eSWilliam A. Kennington III Descriptor& operator=(Descriptor&&) = delete; 210*1bbe3d1eSWilliam A. Kennington III 211*1bbe3d1eSWilliam A. Kennington III explicit Descriptor(int fd) : fd(fd) 212*1bbe3d1eSWilliam A. Kennington III { 213*1bbe3d1eSWilliam A. Kennington III } 214*1bbe3d1eSWilliam A. Kennington III 215*1bbe3d1eSWilliam A. Kennington III /* @brief sets the internal file descriptor with the given descriptor 216*1bbe3d1eSWilliam A. Kennington III * and closes the old descriptor. 217*1bbe3d1eSWilliam A. Kennington III * @param[in] descriptor - File/Socket descriptor. 218*1bbe3d1eSWilliam A. Kennington III */ 219*1bbe3d1eSWilliam A. Kennington III void set(int descriptor) 220*1bbe3d1eSWilliam A. Kennington III { 221*1bbe3d1eSWilliam A. Kennington III // same descriptor given 222*1bbe3d1eSWilliam A. Kennington III if (fd == descriptor) 223*1bbe3d1eSWilliam A. Kennington III { 224*1bbe3d1eSWilliam A. Kennington III return; 225*1bbe3d1eSWilliam A. Kennington III } 226*1bbe3d1eSWilliam A. Kennington III 227*1bbe3d1eSWilliam A. Kennington III // close the old descriptor 228*1bbe3d1eSWilliam A. Kennington III if (fd >= 0) 229*1bbe3d1eSWilliam A. Kennington III { 230*1bbe3d1eSWilliam A. Kennington III close(fd); 231*1bbe3d1eSWilliam A. Kennington III } 232*1bbe3d1eSWilliam A. Kennington III 233*1bbe3d1eSWilliam A. Kennington III fd = descriptor; 234*1bbe3d1eSWilliam A. Kennington III } 235*1bbe3d1eSWilliam A. Kennington III 236*1bbe3d1eSWilliam A. Kennington III ~Descriptor() 237*1bbe3d1eSWilliam A. Kennington III { 238*1bbe3d1eSWilliam A. Kennington III if (fd >= 0) 239*1bbe3d1eSWilliam A. Kennington III { 240*1bbe3d1eSWilliam A. Kennington III close(fd); 241*1bbe3d1eSWilliam A. Kennington III } 242*1bbe3d1eSWilliam A. Kennington III } 243*1bbe3d1eSWilliam A. Kennington III 244*1bbe3d1eSWilliam A. Kennington III int operator()() const 245*1bbe3d1eSWilliam A. Kennington III { 246*1bbe3d1eSWilliam A. Kennington III return fd; 247*1bbe3d1eSWilliam A. Kennington III } 248*1bbe3d1eSWilliam A. Kennington III }; 249*1bbe3d1eSWilliam A. Kennington III 250*1bbe3d1eSWilliam A. Kennington III } // namespace phosphor 251