blob: 251aa0d8284072d9873395fe420cc9bdbe17b4fa [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
Alvin Wang38a63c32019-08-29 22:56:46 +08005#include "ethernet_interface.hpp"
Ratan Gupta3681a502017-06-17 19:20:04 +05306#include "types.hpp"
Patrick Venture189d44e2018-07-09 12:30:59 -07007
William A. Kennington III4966e962019-04-08 01:58:10 -07008#include <netinet/ether.h>
Patrick Venture189d44e2018-07-09 12:30:59 -07009#include <unistd.h>
10
William A. Kennington III4966e962019-04-08 01:58:10 -070011#include <cstring>
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -070012#include <optional>
Patrick Venture189d44e2018-07-09 12:30:59 -070013#include <sdbusplus/bus.hpp>
William A. Kennington IIId27410f2019-01-30 17:15:43 -080014#include <string>
William A. Kennington IIIa00b1c32019-02-01 18:57:17 -080015#include <string_view>
Ratan Gupta8804feb2017-05-25 10:49:57 +053016
17namespace phosphor
18{
19namespace network
20{
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -050021
22constexpr auto IPV4_MIN_PREFIX_LENGTH = 1;
23constexpr auto IPV4_MAX_PREFIX_LENGTH = 32;
24constexpr auto IPV6_MAX_PREFIX_LENGTH = 64;
25constexpr auto IPV4_PREFIX = "169.254";
26constexpr auto IPV6_PREFIX = "fe80";
27
Ratan Guptabd303b12017-08-18 17:10:07 +053028namespace mac_address
29{
30
Ratan Guptabd303b12017-08-18 17:10:07 +053031/** @brief gets the MAC address from the Inventory.
32 * @param[in] bus - DBUS Bus Object.
Alvin Wang38a63c32019-08-29 22:56:46 +080033 * @param[in] intfName - Interface name
Ratan Guptabd303b12017-08-18 17:10:07 +053034 */
Alvin Wang38a63c32019-08-29 22:56:46 +080035ether_addr getfromInventory(sdbusplus::bus::bus& bus,
36 const std::string& intfName);
William A. Kennington III1137a972019-04-20 20:49:58 -070037
38/** @brief Converts the given mac address into byte form
39 * @param[in] str - The mac address in human readable form
40 * @returns A mac address in network byte order
41 * @throws std::runtime_error for bad mac
42 */
43ether_addr fromString(const char* str);
44inline ether_addr fromString(const std::string& str)
45{
46 return fromString(str.c_str());
47}
Ratan Guptabd303b12017-08-18 17:10:07 +053048
William A. Kennington IIId27410f2019-01-30 17:15:43 -080049/** @brief Converts the given mac address bytes into a string
William A. Kennington III1137a972019-04-20 20:49:58 -070050 * @param[in] mac - The mac address
William A. Kennington IIId27410f2019-01-30 17:15:43 -080051 * @returns A valid mac address string
52 */
William A. Kennington III6ca08d82019-04-20 16:04:18 -070053std::string toString(const ether_addr& mac);
William A. Kennington IIId27410f2019-01-30 17:15:43 -080054
William A. Kennington III1137a972019-04-20 20:49:58 -070055/** @brief Determines if the mac address is empty
56 * @param[in] mac - The mac address
57 * @return True if 00:00:00:00:00:00
Ratan Guptabd303b12017-08-18 17:10:07 +053058 */
William A. Kennington III1137a972019-04-20 20:49:58 -070059bool isEmpty(const ether_addr& mac);
Ratan Guptabd303b12017-08-18 17:10:07 +053060
William A. Kennington III1137a972019-04-20 20:49:58 -070061/** @brief Determines if the mac address is a multicast address
62 * @param[in] mac - The mac address
63 * @return True if multicast bit is set
64 */
65bool isMulticast(const ether_addr& mac);
66
67/** @brief Determines if the mac address is a unicast address
68 * @param[in] mac - The mac address
69 * @return True if not multicast or empty
70 */
71bool isUnicast(const ether_addr& mac);
72
73/** @brief Determines if the mac address is locally managed
74 * @param[in] mac - The mac address
75 * @return True if local admin bit is set
76 */
77bool isLocalAdmin(const ether_addr& mac);
78
Gunnar Mills57d9c502018-09-14 14:42:34 -050079} // namespace mac_address
Ratan Gupta8804feb2017-05-25 10:49:57 +053080
Ratan Gupta497c0c92017-08-22 19:15:59 +053081constexpr auto networkdService = "systemd-networkd.service";
82constexpr auto timeSynchdService = "systemd-timesyncd.service";
83
Ratan Gupta8804feb2017-05-25 10:49:57 +053084/* @brief converts the given subnet into prefix notation.
85 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
86 * @param[in] mask - Subnet Mask.
87 * @returns prefix.
88 */
89uint8_t toCidr(int addressFamily, const std::string& mask);
90
William A. Kennington IIIa00b1c32019-02-01 18:57:17 -080091/* @brief converts a sockaddr for the specified address family into
92 * a type_safe InAddrAny.
93 * @param[in] addressFamily - The address family of the buf
94 * @param[in] buf - The network byte order address
95 */
96InAddrAny addrFromBuf(int addressFamily, std::string_view buf);
97
William A. Kennington III5058f572019-01-30 17:18:14 -080098/* @brief converts the ip bytes into a string representation
99 * @param[in] addr - input ip address to convert.
100 * @returns String representation of the ip.
101 */
102std::string toString(const InAddrAny& addr);
103
Ratan Gupta8804feb2017-05-25 10:49:57 +0530104/* @brief converts the prefix into subnetmask.
105 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
106 * @param[in] prefix - prefix length.
107 * @returns subnet mask.
108 */
109std::string toMask(int addressFamily, uint8_t prefix);
110
111/* @brief checks that the given ip address is link local or not.
112 * @param[in] address - IP address.
113 * @returns true if it is linklocal otherwise false.
114 */
Nagaraju Goruganti66b974d2017-10-03 08:43:08 -0500115bool isLinkLocalIP(const std::string& address);
116
117/* @brief checks that the given ip address valid or not.
118 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
119 * @param[in] address - IP address.
120 * @returns true if it is valid otherwise false.
121 */
122bool isValidIP(int addressFamily, const std::string& address);
123
124/* @brief checks that the given prefix is valid or not.
125 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
126 * @param[in] prefix - prefix length.
127 * @returns true if it is valid otherwise false.
128 */
129bool isValidPrefix(int addressFamily, uint8_t prefixLength);
Ratan Gupta8804feb2017-05-25 10:49:57 +0530130
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530131/** @brief Gets the map of interface and the associated
132 * address.
133 * @returns map of interface and the address.
Ratan Gupta3681a502017-06-17 19:20:04 +0530134 */
135IntfAddrMap getInterfaceAddrs();
136
Ratan Guptafd4b0f02017-09-16 06:01:24 +0530137/** @brief Get all the interfaces from the system.
138 * @returns list of interface names.
139 */
140InterfaceList getInterfaces();
141
Ratan Guptabc886292017-07-25 18:29:57 +0530142/** @brief Delete the given interface.
143 * @param[in] intf - interface name.
144 */
145void deleteInterface(const std::string& intf);
146
William A. Kennington III7b9e8bd2019-04-23 19:31:31 -0700147/** @brief Converts the interface name into a u-boot environment
148 * variable that would hold its ethernet address.
149 *
150 * @param[in] intf - interface name
151 * @return The name of th environment key
152 */
153std::optional<std::string> interfaceToUbootEthAddr(const char* intf);
154
Ratan Gupta56187e72017-08-13 09:40:14 +0530155/** @brief read the DHCP value from the configuration file
156 * @param[in] confDir - Network configuration directory.
157 * @param[in] intf - Interface name.
158 */
159bool getDHCPValue(const std::string& confDir, const std::string& intf);
Ratan Guptabc886292017-07-25 18:29:57 +0530160
Ratan Guptabd303b12017-08-18 17:10:07 +0530161namespace internal
162{
163
164/* @brief runs the given command in child process.
165 * @param[in] path - path of the binary file which needs to be execeuted.
166 * @param[in] args - arguments of the command.
167 */
168void executeCommandinChildProcess(const char* path, char** args);
169
170} // namespace internal
171
172/* @brief runs the given command in child process.
173 * @param[in] path -path of the binary file which needs to be execeuted.
174 * @param[in] tArgs - arguments of the command.
175 */
Gunnar Mills57d9c502018-09-14 14:42:34 -0500176template <typename... ArgTypes>
Ratan Guptabd303b12017-08-18 17:10:07 +0530177void execute(const char* path, ArgTypes&&... tArgs)
178{
William A. Kennington III0420c6a2019-06-27 14:38:17 -0700179 using expandType = char*[];
Ratan Guptabd303b12017-08-18 17:10:07 +0530180
Gunnar Mills57d9c502018-09-14 14:42:34 -0500181 expandType args = {const_cast<char*>(tArgs)..., nullptr};
Ratan Guptabd303b12017-08-18 17:10:07 +0530182
183 internal::executeCommandinChildProcess(path, args);
184}
185
Gunnar Mills57d9c502018-09-14 14:42:34 -0500186} // namespace network
Ratan Gupta8804feb2017-05-25 10:49:57 +0530187
William A. Kennington IIIc920bdb2019-04-19 14:23:06 -0700188/** @brief Copies data from a buffer into a copyable type
189 *
190 * @param[in] data - The data buffer being extracted from
191 * @param[in] emsg - The message to print if extraction fails
192 * @return The copyable type with data populated
193 */
194template <typename T>
195T copyFrom(std::string_view data, const char* emsg = "Extract Failed")
196{
197 static_assert(std::is_trivially_copyable_v<T>);
198 T ret;
199 if (data.size() < sizeof(ret))
200 {
201 throw std::runtime_error(emsg);
202 }
203 std::memcpy(&ret, data.data(), sizeof(ret));
204 return ret;
205}
206
207/** @brief Extracts data from a buffer into a copyable type
208 * Updates the data buffer to show that data was removed
209 *
210 * @param[in,out] data - The data buffer being extracted from
211 * @param[in] emsg - The message to print if extraction fails
212 * @return The copyable type with data populated
213 */
214template <typename T>
215T extract(std::string_view& data, const char* emsg = "Extract Failed")
216{
217 T ret = copyFrom<T>(data, emsg);
218 data.remove_prefix(sizeof(ret));
219 return ret;
220}
221
222/** @brief Compares two of the same trivially copyable types
223 *
224 * @param[in] a - The data buffer being extracted from
225 * @param[in] b - The message to print if extraction fails
226 * @return True if the parameters are bitwise identical
227 */
228template <typename T>
229bool equal(const T& a, const T& b)
230{
231 static_assert(std::is_trivially_copyable_v<T>);
232 return memcmp(&a, &b, sizeof(T)) == 0;
233}
234
Ratan Gupta8804feb2017-05-25 10:49:57 +0530235class Descriptor
236{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500237 private:
238 /** default value */
239 int fd = -1;
Ratan Gupta8804feb2017-05-25 10:49:57 +0530240
Gunnar Mills57d9c502018-09-14 14:42:34 -0500241 public:
242 Descriptor() = default;
243 Descriptor(const Descriptor&) = delete;
244 Descriptor& operator=(const Descriptor&) = delete;
245 Descriptor(Descriptor&&) = delete;
246 Descriptor& operator=(Descriptor&&) = delete;
Ratan Gupta8804feb2017-05-25 10:49:57 +0530247
Gunnar Mills57d9c502018-09-14 14:42:34 -0500248 explicit Descriptor(int fd) : fd(fd)
249 {
250 }
Ratan Gupta8804feb2017-05-25 10:49:57 +0530251
Gunnar Mills57d9c502018-09-14 14:42:34 -0500252 /* @brief sets the internal file descriptor with the given descriptor
253 * and closes the old descriptor.
254 * @param[in] descriptor - File/Socket descriptor.
255 */
256 void set(int descriptor)
257 {
258 // same descriptor given
259 if (fd == descriptor)
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530260 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500261 return;
Ratan Gupta0f9dc1b2017-09-03 17:57:50 +0530262 }
263
Gunnar Mills57d9c502018-09-14 14:42:34 -0500264 // close the old descriptor
265 if (fd >= 0)
Ratan Gupta8804feb2017-05-25 10:49:57 +0530266 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500267 close(fd);
Ratan Gupta8804feb2017-05-25 10:49:57 +0530268 }
269
Gunnar Mills57d9c502018-09-14 14:42:34 -0500270 fd = descriptor;
271 }
272
273 ~Descriptor()
274 {
275 if (fd >= 0)
Ratan Gupta8804feb2017-05-25 10:49:57 +0530276 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500277 close(fd);
Ratan Gupta8804feb2017-05-25 10:49:57 +0530278 }
Gunnar Mills57d9c502018-09-14 14:42:34 -0500279 }
280
281 int operator()() const
282 {
283 return fd;
284 }
Ratan Gupta8804feb2017-05-25 10:49:57 +0530285};
286
Gunnar Mills57d9c502018-09-14 14:42:34 -0500287} // namespace phosphor