summaryrefslogtreecommitdiffstats
path: root/util.hpp
blob: 0f03af3d132f5d048a82b5e0dd4a3b637201a404 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#pragma once

#include "config.h"

#include "types.hpp"

#include <netinet/ether.h>
#include <unistd.h>

#include <cstring>
#include <sdbusplus/bus.hpp>
#include <string>
#include <string_view>

namespace phosphor
{
namespace network
{

constexpr auto IPV4_MIN_PREFIX_LENGTH = 1;
constexpr auto IPV4_MAX_PREFIX_LENGTH = 32;
constexpr auto IPV6_MAX_PREFIX_LENGTH = 64;
constexpr auto IPV4_PREFIX = "169.254";
constexpr auto IPV6_PREFIX = "fe80";

namespace mac_address
{

constexpr auto localAdminMask = 0x020000000000;
constexpr auto broadcastMac = 0xFFFFFFFFFFFF;

constexpr auto format = "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx";
constexpr size_t size = 18;

/** @brief validate the mac address
 *  @param[in] value - MAC address.
 *  @returns true if validate otherwise false.
 */
inline bool validate(const std::string& value)
{
    struct ether_addr* addr = ether_aton(value.c_str());
    if (addr == nullptr)
    {
        return false;
    }
    ether_addr zero{};
    return std::memcmp(addr, &zero, sizeof(zero)) != 0;
}

/** @brief gets the MAC address from the Inventory.
 *  @param[in] bus - DBUS Bus Object.
 */
std::string getfromInventory(sdbusplus::bus::bus& bus);

/* @brief Marshalls the bytes for a mac address into a MacAddr.
 * @param[in] buf - The network byte order address
 */
MacAddr fromBuf(std::string_view buf);

/** @brief Converts the given mac address bytes into a string
 *  @param[in] bytes - The mac address
 *  @returns A valid mac address string
 */
std::string toString(const MacAddr& mac);

namespace internal
{
/** @brief Converts the given mac address into unsigned 64 bit integer
 *  @param[in] value - MAC address.
 *  @returns converted unsigned 64 bit number.
 */
inline uint64_t convertToInt(const std::string& value)
{
    struct ether_addr* addr = ether_aton(value.c_str());
    if (addr == nullptr)
    {
        return 0;
    }
    uint64_t ret = 0;
    static_assert(sizeof(ret) >= sizeof(*addr));
    std::memcpy(&ret, addr, sizeof(*addr));
    return ret;
}

/** @brief Converts the lower nibble of a byte value to a hex digit
 */
inline char toHex(std::byte byte)
{
    uint8_t val = std::to_integer<uint8_t>(byte) & 0xf;
    return val < 10 ? '0' + val : 'A' + (val - 10);
}
} // namespace internal
} // namespace mac_address

constexpr auto networkdService = "systemd-networkd.service";
constexpr auto timeSynchdService = "systemd-timesyncd.service";

/* @brief converts the given subnet into prefix notation.
 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
 * @param[in] mask - Subnet Mask.
 * @returns prefix.
 */
uint8_t toCidr(int addressFamily, const std::string& mask);

/* @brief converts a sockaddr for the specified address family into
 *        a type_safe InAddrAny.
 * @param[in] addressFamily - The address family of the buf
 * @param[in] buf - The network byte order address
 */
InAddrAny addrFromBuf(int addressFamily, std::string_view buf);

/* @brief converts the ip bytes into a string representation
 * @param[in] addr - input ip address to convert.
 * @returns String representation of the ip.
 */
std::string toString(const InAddrAny& addr);

/* @brief converts the prefix into subnetmask.
 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
 * @param[in] prefix - prefix length.
 * @returns subnet mask.
 */
std::string toMask(int addressFamily, uint8_t prefix);

/* @brief checks that the given ip address is link local or not.
 * @param[in] address - IP address.
 * @returns true if it is linklocal otherwise false.
 */
bool isLinkLocalIP(const std::string& address);

/* @brief checks that the given ip address valid or not.
 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
 * @param[in] address - IP address.
 * @returns true if it is valid otherwise false.
 */
bool isValidIP(int addressFamily, const std::string& address);

/* @brief checks that the given prefix is valid or not.
 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
 * @param[in] prefix - prefix length.
 * @returns true if it is valid otherwise false.
 */
bool isValidPrefix(int addressFamily, uint8_t prefixLength);

/* @brief gets the network section of the ip address.
 * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
 * @param[in] ipaddress - IP address.
 * @param[in] prefix - prefix length.
 * @returns network section of the ipaddress.
 */
std::string getNetworkID(int addressFamily, const std::string& ipaddress,
                         uint8_t prefix);

/** @brief Gets the map of interface and the associated
 *         address.
 *  @returns map of interface and the address.
 */
IntfAddrMap getInterfaceAddrs();

/** @brief Get all the interfaces from the system.
 *  @returns list of interface names.
 */
InterfaceList getInterfaces();

/** @brief Delete the given interface.
 *  @param[in] intf - interface name.
 */
void deleteInterface(const std::string& intf);

/** @brief read the DHCP value from the configuration file
 *  @param[in] confDir - Network configuration directory.
 *  @param[in] intf - Interface name.
 */
bool getDHCPValue(const std::string& confDir, const std::string& intf);

namespace internal
{

/* @brief runs the given command in child process.
 * @param[in] path - path of the binary file which needs to be execeuted.
 * @param[in] args - arguments of the command.
 */
void executeCommandinChildProcess(const char* path, char** args);

} // namespace internal

/* @brief runs the given command in child process.
 * @param[in] path -path of the binary file which needs to be execeuted.
 * @param[in] tArgs - arguments of the command.
 */
template <typename... ArgTypes>
void execute(const char* path, ArgTypes&&... tArgs)
{
    using expandType = char* [];

    expandType args = {const_cast<char*>(tArgs)..., nullptr};

    internal::executeCommandinChildProcess(path, args);
}

} // namespace network

class Descriptor
{
  private:
    /** default value */
    int fd = -1;

  public:
    Descriptor() = default;
    Descriptor(const Descriptor&) = delete;
    Descriptor& operator=(const Descriptor&) = delete;
    Descriptor(Descriptor&&) = delete;
    Descriptor& operator=(Descriptor&&) = delete;

    explicit Descriptor(int fd) : fd(fd)
    {
    }

    /* @brief sets the internal file descriptor with the given descriptor
     *        and closes the old descriptor.
     * @param[in] descriptor - File/Socket descriptor.
     */
    void set(int descriptor)
    {
        // same descriptor given
        if (fd == descriptor)
        {
            return;
        }

        // close the old descriptor
        if (fd >= 0)
        {
            close(fd);
        }

        fd = descriptor;
    }

    ~Descriptor()
    {
        if (fd >= 0)
        {
            close(fd);
        }
    }

    int operator()() const
    {
        return fd;
    }
};

} // namespace phosphor
OpenPOWER on IntegriCloud