xref: /openbmc/phosphor-networkd/src/util.hpp (revision 96444795)
1 #pragma once
2 #include "types.hpp"
3 
4 #include <netinet/ether.h>
5 #include <netinet/in.h>
6 #include <unistd.h>
7 
8 #include <cstring>
9 #include <filesystem>
10 #include <optional>
11 #include <sdbusplus/bus.hpp>
12 #include <stdplus/zstring.hpp>
13 #include <string>
14 #include <string_view>
15 #include <unordered_set>
16 #include <xyz/openbmc_project/Network/EthernetInterface/server.hpp>
17 
18 namespace phosphor
19 {
20 namespace network
21 {
22 namespace config
23 {
24 class Parser;
25 }
26 
27 using EthernetInterfaceIntf =
28     sdbusplus::xyz::openbmc_project::Network::server::EthernetInterface;
29 
30 namespace mac_address
31 {
32 
33 /** @brief gets the MAC address from the Inventory.
34  *  @param[in] bus - DBUS Bus Object.
35  *  @param[in] intfName - Interface name
36  */
37 ether_addr getfromInventory(sdbusplus::bus_t& bus, const std::string& intfName);
38 
39 /** @brief Converts the given mac address into byte form
40  *  @param[in] str - The mac address in human readable form
41  *  @returns A mac address in network byte order
42  *  @throws std::runtime_error for bad mac
43  */
44 ether_addr fromString(std::string_view str);
45 
46 /** @brief Converts the given mac address bytes into a string
47  *  @param[in] mac - The mac address
48  *  @returns A valid mac address string
49  */
50 std::string toString(const ether_addr& mac);
51 
52 /** @brief Determines if the mac address is empty
53  *  @param[in] mac - The mac address
54  *  @return True if 00:00:00:00:00:00
55  */
56 bool isEmpty(const ether_addr& mac);
57 
58 /** @brief Determines if the mac address is a multicast address
59  *  @param[in] mac - The mac address
60  *  @return True if multicast bit is set
61  */
62 bool isMulticast(const ether_addr& mac);
63 
64 /** @brief Determines if the mac address is a unicast address
65  *  @param[in] mac - The mac address
66  *  @return True if not multicast or empty
67  */
68 bool isUnicast(const ether_addr& mac);
69 
70 } // namespace mac_address
71 
72 constexpr auto networkdService = "systemd-networkd.service";
73 constexpr auto timeSynchdService = "systemd-timesyncd.service";
74 
75 template <int family>
76 struct FamilyTraits
77 {
78 };
79 
80 template <>
81 struct FamilyTraits<AF_INET>
82 {
83     using addr = in_addr;
84     static constexpr std::size_t strlen = INET_ADDRSTRLEN;
85 };
86 
87 template <>
88 struct FamilyTraits<AF_INET6>
89 {
90     using addr = in6_addr;
91     static constexpr std::size_t strlen = INET6_ADDRSTRLEN;
92 };
93 
94 template <typename Addr>
95 struct AddrToFamily
96 {
97 };
98 
99 template <>
100 struct AddrToFamily<in_addr>
101 {
102     static constexpr int value = AF_INET;
103 };
104 
105 template <>
106 struct AddrToFamily<in6_addr>
107 {
108     static constexpr int value = AF_INET6;
109 };
110 
111 /* @brief converts a sockaddr for the specified address family into
112  *        a type_safe InAddrAny.
113  * @param[in] family - The address family of the buf
114  * @param[in] buf - The network byte order address
115  */
116 template <int family>
117 typename FamilyTraits<family>::addr addrFromBuf(std::string_view buf);
118 InAddrAny addrFromBuf(int family, std::string_view buf);
119 
120 /* @brief converts the ip bytes into a string representation
121  * @param[in] addr - input ip address to convert.
122  * @returns String representation of the ip.
123  */
124 template <typename Addr>
125 std::string toString(const Addr& addr);
126 std::string toString(const InAddrAny& addr);
127 
128 /* @brief checks that the given ip address valid or not.
129  * @param[in] family - IP address family(AF_INET/AF_INET6).
130  * @param[in] address - IP address.
131  * @returns true if it is valid otherwise false.
132  */
133 bool isValidIP(int family, stdplus::const_zstring address) noexcept;
134 bool isValidIP(stdplus::const_zstring address) noexcept;
135 
136 /* @brief checks that the given prefix is valid or not.
137  * @param[in] family - IP address family(AF_INET/AF_INET6).
138  * @param[in] prefix - prefix length.
139  * @returns true if it is valid otherwise false.
140  */
141 template <int family>
142 constexpr bool isValidPrefix(uint8_t prefix) noexcept
143 {
144     return prefix <= sizeof(typename FamilyTraits<family>::addr) * 8;
145 }
146 bool isValidPrefix(int family, uint8_t prefixLength);
147 
148 /** @brief Get all the interfaces from the system.
149  *  @returns list of interface names.
150  */
151 string_uset getSystemInterfaces();
152 
153 /** @brief Delete the given interface.
154  *  @param[in] intf - interface name.
155  */
156 void deleteInterface(stdplus::const_zstring intf);
157 
158 /** @brief Converts the interface name into a u-boot environment
159  *         variable that would hold its ethernet address.
160  *
161  *  @param[in] intf - interface name
162  *  @return The name of th environment key
163  */
164 std::optional<std::string> interfaceToUbootEthAddr(std::string_view intf);
165 
166 /** @brief read the IPv6AcceptRA value from the configuration file
167  *  @param[in] config - The parsed configuration.
168  */
169 bool getIPv6AcceptRA(const config::Parser& config);
170 
171 /** @brief read the DHCP value from the configuration file
172  *  @param[in] config - The parsed configuration.
173  */
174 struct DHCPVal
175 {
176     bool v4, v6;
177 };
178 DHCPVal getDHCPValue(const config::Parser& config);
179 
180 /** @brief Read a boolean DHCP property from a conf file
181  *  @param[in] config - The parsed configuration.
182  *  @param[in] key - The property name.
183  */
184 bool getDHCPProp(const config::Parser& config, std::string_view key);
185 
186 namespace internal
187 {
188 
189 /* @brief runs the given command in child process.
190  * @param[in] path - path of the binary file which needs to be execeuted.
191  * @param[in] args - arguments of the command.
192  */
193 void executeCommandinChildProcess(stdplus::const_zstring path, char** args);
194 
195 /** @brief Get ignored interfaces from environment */
196 std::string_view getIgnoredInterfacesEnv();
197 
198 /** @brief Parse the comma separated interface names */
199 std::unordered_set<std::string_view>
200     parseInterfaces(std::string_view interfaces);
201 
202 /** @brief Get the ignored interfaces */
203 const std::unordered_set<std::string_view>& getIgnoredInterfaces();
204 
205 } // namespace internal
206 
207 /* @brief runs the given command in child process.
208  * @param[in] path -path of the binary file which needs to be execeuted.
209  * @param[in] tArgs - arguments of the command.
210  */
211 template <typename... ArgTypes>
212 void execute(stdplus::const_zstring path, ArgTypes&&... tArgs)
213 {
214     using expandType = char*[];
215 
216     expandType args = {const_cast<char*>(tArgs)..., nullptr};
217 
218     internal::executeCommandinChildProcess(path, args);
219 }
220 
221 } // namespace network
222 
223 } // namespace phosphor
224