blob: 3aad4a1deb5d93dae5bde562cf4cbd8a9ef36431 [file] [log] [blame]
Ratan Gupta8804feb2017-05-25 10:49:57 +05301#pragma once
2
Ratan Gupta068a8cf2017-07-11 19:18:29 +05303#include "config.h"
Gunnar Mills57d9c502018-09-14 14:42:34 -05004
Ratan Gupta3681a502017-06-17 19:20:04 +05305#include "types.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07006
William A. Kennington III4966e962019-04-08 01:58:10 -07007#include <netinet/ether.h>
Patrick Venture189d44e2018-07-09 12:30:59 -07008#include <unistd.h>
9
William A. Kennington III4966e962019-04-08 01:58:10 -070010#include <cstring>
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -070011#include <optional>
Patrick Venture189d44e2018-07-09 12:30:59 -070012#include <sdbusplus/bus.hpp>
William A. Kennington IIId27410f2019-01-30 17:15:43 -080013#include <string>
William A. Kennington IIIa00b1c32019-02-01 18:57:17 -080014#include <string_view>
Ratan Gupta8804feb2017-05-25 10:49:57 +053015
16namespace phosphor
17{
18namespace network
19{
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050020
21constexpr auto IPV4_MIN_PREFIX_LENGTH = 1;
22constexpr auto IPV4_MAX_PREFIX_LENGTH = 32;
23constexpr auto IPV6_MAX_PREFIX_LENGTH = 64;
24constexpr auto IPV4_PREFIX = "169.254";
25constexpr auto IPV6_PREFIX = "fe80";
26
Ratan Guptabd303b12017-08-18 17:10:07 +053027namespace mac_address
28{
29
Ratan Guptabd303b12017-08-18 17:10:07 +053030/** @brief gets the MAC address from the Inventory.
31 * @param[in] bus - DBUS Bus Object.
32 */
William A. Kennington III1137a972019-04-20 20:49:58 -070033ether_addr getfromInventory(sdbusplus::bus::bus& bus);
34
35/** @brief Converts the given mac address into byte form
36 * @param[in] str - The mac address in human readable form
37 * @returns A mac address in network byte order
38 * @throws std::runtime_error for bad mac
39 */
40ether_addr fromString(const char* str);
41inline ether_addr fromString(const std::string& str)
42{
43 return fromString(str.c_str());
44}
Ratan Guptabd303b12017-08-18 17:10:07 +053045
William A. Kennington IIId27410f2019-01-30 17:15:43 -080046/** @brief Converts the given mac address bytes into a string
William A. Kennington III1137a972019-04-20 20:49:58 -070047 * @param[in] mac - The mac address
William A. Kennington IIId27410f2019-01-30 17:15:43 -080048 * @returns A valid mac address string
49 */
William A. Kennington III6ca08d82019-04-20 16:04:18 -070050std::string toString(const ether_addr& mac);
William A. Kennington IIId27410f2019-01-30 17:15:43 -080051
William A. Kennington III1137a972019-04-20 20:49:58 -070052/** @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
Ratan Guptabd303b12017-08-18 17:10:07 +053055 */
William A. Kennington III1137a972019-04-20 20:49:58 -070056bool isEmpty(const ether_addr& mac);
Ratan Guptabd303b12017-08-18 17:10:07 +053057
William A. Kennington III1137a972019-04-20 20:49:58 -070058/** @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 */
62bool 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 */
68bool isUnicast(const ether_addr& mac);
69
70/** @brief Determines if the mac address is locally managed
71 * @param[in] mac - The mac address
72 * @return True if local admin bit is set
73 */
74bool isLocalAdmin(const ether_addr& mac);
75
Gunnar Mills57d9c502018-09-14 14:42:34 -050076} // namespace mac_address
Ratan Gupta8804feb2017-05-25 10:49:57 +053077
Ratan Gupta497c0c92017-08-22 19:15:59 +053078constexpr auto networkdService = "systemd-networkd.service";
79constexpr auto timeSynchdService = "systemd-timesyncd.service";
80
Ratan Gupta8804feb2017-05-25 10:49:57 +053081/* @brief converts the given subnet into prefix notation.
82 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
83 * @param[in] mask - Subnet Mask.
84 * @returns prefix.
85 */
86uint8_t toCidr(int addressFamily, const std::string& mask);
87
William A. Kennington IIIa00b1c32019-02-01 18:57:17 -080088/* @brief converts a sockaddr for the specified address family into
89 * a type_safe InAddrAny.
90 * @param[in] addressFamily - The address family of the buf
91 * @param[in] buf - The network byte order address
92 */
93InAddrAny addrFromBuf(int addressFamily, std::string_view buf);
94
William A. Kennington III5058f572019-01-30 17:18:14 -080095/* @brief converts the ip bytes into a string representation
96 * @param[in] addr - input ip address to convert.
97 * @returns String representation of the ip.
98 */
99std::string toString(const InAddrAny& addr);
100
Ratan Gupta8804feb2017-05-25 10:49:57 +0530101/* @brief converts the prefix into subnetmask.
102 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
103 * @param[in] prefix - prefix length.
104 * @returns subnet mask.
105 */
106std::string toMask(int addressFamily, uint8_t prefix);
107
108/* @brief checks that the given ip address is link local or not.
109 * @param[in] address - IP address.
110 * @returns true if it is linklocal otherwise false.
111 */
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500112bool isLinkLocalIP(const std::string& address);
113
114/* @brief checks that the given ip address valid or not.
115 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
116 * @param[in] address - IP address.
117 * @returns true if it is valid otherwise false.
118 */
119bool isValidIP(int addressFamily, const std::string& address);
120
121/* @brief checks that the given prefix is valid or not.
122 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
123 * @param[in] prefix - prefix length.
124 * @returns true if it is valid otherwise false.
125 */
126bool isValidPrefix(int addressFamily, uint8_t prefixLength);
Ratan Gupta8804feb2017-05-25 10:49:57 +0530127
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530128/** @brief Gets the map of interface and the associated
129 * address.
130 * @returns map of interface and the address.
Ratan Gupta3681a502017-06-17 19:20:04 +0530131 */
132IntfAddrMap getInterfaceAddrs();
133
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530134/** @brief Get all the interfaces from the system.
135 * @returns list of interface names.
136 */
137InterfaceList getInterfaces();
138
Ratan Guptabc886292017-07-25 18:29:57 +0530139/** @brief Delete the given interface.
140 * @param[in] intf - interface name.
141 */
142void deleteInterface(const std::string& intf);
143
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700144/** @brief Converts the interface name into a u-boot environment
145 * variable that would hold its ethernet address.
146 *
147 * @param[in] intf - interface name
148 * @return The name of th environment key
149 */
150std::optional<std::string> interfaceToUbootEthAddr(const char* intf);
151
Ratan Gupta56187e72017-08-13 09:40:14 +0530152/** @brief read the DHCP value from the configuration file
153 * @param[in] confDir - Network configuration directory.
154 * @param[in] intf - Interface name.
155 */
156bool getDHCPValue(const std::string& confDir, const std::string& intf);
Ratan Guptabc886292017-07-25 18:29:57 +0530157
Ratan Guptabd303b12017-08-18 17:10:07 +0530158namespace internal
159{
160
161/* @brief runs the given command in child process.
162 * @param[in] path - path of the binary file which needs to be execeuted.
163 * @param[in] args - arguments of the command.
164 */
165void executeCommandinChildProcess(const char* path, char** args);
166
167} // namespace internal
168
169/* @brief runs the given command in child process.
170 * @param[in] path -path of the binary file which needs to be execeuted.
171 * @param[in] tArgs - arguments of the command.
172 */
Gunnar Mills57d9c502018-09-14 14:42:34 -0500173template <typename... ArgTypes>
Ratan Guptabd303b12017-08-18 17:10:07 +0530174void execute(const char* path, ArgTypes&&... tArgs)
175{
William A. Kennington III0420c6a2019-06-27 14:38:17 -0700176 using expandType = char*[];
Ratan Guptabd303b12017-08-18 17:10:07 +0530177
Gunnar Mills57d9c502018-09-14 14:42:34 -0500178 expandType args = {const_cast<char*>(tArgs)..., nullptr};
Ratan Guptabd303b12017-08-18 17:10:07 +0530179
180 internal::executeCommandinChildProcess(path, args);
181}
182
Gunnar Mills57d9c502018-09-14 14:42:34 -0500183} // namespace network
Ratan Gupta8804feb2017-05-25 10:49:57 +0530184
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700185/** @brief Copies data from a buffer into a copyable type
186 *
187 * @param[in] data - The data buffer being extracted from
188 * @param[in] emsg - The message to print if extraction fails
189 * @return The copyable type with data populated
190 */
191template <typename T>
192T copyFrom(std::string_view data, const char* emsg = "Extract Failed")
193{
194 static_assert(std::is_trivially_copyable_v<T>);
195 T ret;
196 if (data.size() < sizeof(ret))
197 {
198 throw std::runtime_error(emsg);
199 }
200 std::memcpy(&ret, data.data(), sizeof(ret));
201 return ret;
202}
203
204/** @brief Extracts data from a buffer into a copyable type
205 * Updates the data buffer to show that data was removed
206 *
207 * @param[in,out] data - The data buffer being extracted from
208 * @param[in] emsg - The message to print if extraction fails
209 * @return The copyable type with data populated
210 */
211template <typename T>
212T extract(std::string_view& data, const char* emsg = "Extract Failed")
213{
214 T ret = copyFrom<T>(data, emsg);
215 data.remove_prefix(sizeof(ret));
216 return ret;
217}
218
219/** @brief Compares two of the same trivially copyable types
220 *
221 * @param[in] a - The data buffer being extracted from
222 * @param[in] b - The message to print if extraction fails
223 * @return True if the parameters are bitwise identical
224 */
225template <typename T>
226bool equal(const T& a, const T& b)
227{
228 static_assert(std::is_trivially_copyable_v<T>);
229 return memcmp(&a, &b, sizeof(T)) == 0;
230}
231
Ratan Gupta8804feb2017-05-25 10:49:57 +0530232class Descriptor
233{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500234 private:
235 /** default value */
236 int fd = -1;
Ratan Gupta8804feb2017-05-25 10:49:57 +0530237
Gunnar Mills57d9c502018-09-14 14:42:34 -0500238 public:
239 Descriptor() = default;
240 Descriptor(const Descriptor&) = delete;
241 Descriptor& operator=(const Descriptor&) = delete;
242 Descriptor(Descriptor&&) = delete;
243 Descriptor& operator=(Descriptor&&) = delete;
Ratan Gupta8804feb2017-05-25 10:49:57 +0530244
Gunnar Mills57d9c502018-09-14 14:42:34 -0500245 explicit Descriptor(int fd) : fd(fd)
246 {
247 }
Ratan Gupta8804feb2017-05-25 10:49:57 +0530248
Gunnar Mills57d9c502018-09-14 14:42:34 -0500249 /* @brief sets the internal file descriptor with the given descriptor
250 * and closes the old descriptor.
251 * @param[in] descriptor - File/Socket descriptor.
252 */
253 void set(int descriptor)
254 {
255 // same descriptor given
256 if (fd == descriptor)
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530257 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500258 return;
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530259 }
260
Gunnar Mills57d9c502018-09-14 14:42:34 -0500261 // close the old descriptor
262 if (fd >= 0)
Ratan Gupta8804feb2017-05-25 10:49:57 +0530263 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500264 close(fd);
Ratan Gupta8804feb2017-05-25 10:49:57 +0530265 }
266
Gunnar Mills57d9c502018-09-14 14:42:34 -0500267 fd = descriptor;
268 }
269
270 ~Descriptor()
271 {
272 if (fd >= 0)
Ratan Gupta8804feb2017-05-25 10:49:57 +0530273 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500274 close(fd);
Ratan Gupta8804feb2017-05-25 10:49:57 +0530275 }
Gunnar Mills57d9c502018-09-14 14:42:34 -0500276 }
277
278 int operator()() const
279 {
280 return fd;
281 }
Ratan Gupta8804feb2017-05-25 10:49:57 +0530282};
283
Gunnar Mills57d9c502018-09-14 14:42:34 -0500284} // namespace phosphor