PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
platformLinux.cpp
Go to the documentation of this file.
1
3
4#include "profinet/util.h"
5
6#include <cerrno>
7#include <cstring>
8#include <filesystem>
9#include <net/if.h>
10#include <string>
11#include <span>
12#include <stdexcept>
13#include <sys/ioctl.h>
14#include <sys/socket.h>
15#include <unistd.h>
16
17#include <algorithm>
18
19#include "profinet/exceptions.h"
20
21namespace profinet
22{
23namespace
24{
29MacAddress GetLinuxInterfaceMac(const std::string& interface)
30{
31 if (interface.empty())
32 {
33 throw SocketError("Interface name cannot be empty");
34 }
35
36 if (interface.size() >= IFNAMSIZ)
37 {
38 throw SocketError("Interface name is too long: '" + interface + "'");
39 }
40
41 const int socketFd = ::socket(AF_INET, SOCK_DGRAM, 0);
42
43 if (socketFd < 0)
44 {
45 throw SocketError("Failed to open socket while reading MAC address for '" + interface + "': " +
46 std::strerror(errno));
47 }
48
49 ifreq request{};
50 std::strncpy(request.ifr_name, interface.c_str(), IFNAMSIZ - 1);
51
52 if (::ioctl(socketFd, SIOCGIFHWADDR, &request) < 0)
53 {
54 const int error = errno;
55 ::close(socketFd);
56
57 throw SocketError("Failed to get MAC address for '" + interface + "': " +
58 std::strerror(error));
59 }
60
61 ::close(socketFd);
62
63 MacAddress mac{};
64 std::ranges::copy(
65 std::span<const std::uint8_t>(
66 reinterpret_cast<const std::uint8_t*>(request.ifr_hwaddr.sa_data),
68 mac.begin());
69
70 return mac;
71}
72} // namespace
73
74MacAddress GetInterfaceMac(const std::string& interface)
75{
76 return GetLinuxInterfaceMac(interface);
77}
78
79std::filesystem::path GetExecutableDirectory()
80{
81 static constexpr char kProcessPath[] = "/proc/self/exe";
82
83 try
84 {
85 return std::filesystem::read_symlink(kProcessPath).parent_path();
86 }
87 catch (const std::filesystem::filesystem_error& error)
88 {
89 throw std::runtime_error("Failed to resolve executable path from /proc/self/exe: " +
90 std::string(error.what()));
91 }
92}
93
94} // namespace profinet
Declares exceptions and error types used by the PROFINET IO controller stack.
MacAddress GetInterfaceMac(const std::string &interface)
Get the MAC address assigned to a network interface.
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
Definition util.h:48
std::filesystem::path GetExecutableDirectory()
Retrieves the absolute directory path of the currently running executable.
constexpr int macAddressLength
Constant lenght of a mac address.
Definition util.h:37
asio::error_code error
Declares Linux Ethernet, addressing, timing, and utility helpers used by the PROFINET stack.