xref: /openbmc/dbus-sensors/src/MctpAsioEndpoint.cpp (revision 6ef897399d8c2fb9f005b0c0d0ba3f9bd115965f)
1 #include "MctpAsioEndpoint.hpp"
2 
3 #include <boost/asio/generic/datagram_protocol.hpp>
4 #include <phosphor-logging/lg2.hpp>
5 
6 #include <bit>
7 #include <cstdint>
8 #include <optional>
9 
10 // Becuase of issues with glibc not matching linux, we need to make sure these
11 // are included AFTER the system headers, which are implictly included by boost.
12 // These show up as errors like
13 // /usr/include/net/if.h:44:14: error: ‘IFF_UP’ conflicts with a previous
14 // declaration
15 // The bugs below are other projects working around similar issues
16 // https://bugzilla.redhat.com/show_bug.cgi?id=1300256
17 // https://github.com/systemd/systemd/commit/08ce521fb2546921f2642bef067d2cc02158b121
18 // https://github.com/systemd/systemd/issues/2864
19 // clang-format off
20 #include <linux/mctp.h>
21 #include <sys/socket.h>
22 // clang-format on
23 
MctpAsioEndpoint(uint8_t eid,uint8_t msgType)24 MctpAsioEndpoint::MctpAsioEndpoint(uint8_t eid, uint8_t msgType)
25 {
26     endpoint.resize(sizeof(struct sockaddr_mctp));
27     struct sockaddr_mctp* sock =
28         std::bit_cast<struct sockaddr_mctp*>(endpoint.data());
29     sock->smctp_addr.s_addr = eid;
30     sock->smctp_family = AF_MCTP;
31     sock->smctp_type = msgType;
32     sock->smctp_tag = MCTP_TAG_OWNER;
33     sock->smctp_network = MCTP_NET_ANY;
34 };
35 
MctpAsioEndpoint(uint8_t msgType)36 MctpAsioEndpoint::MctpAsioEndpoint(uint8_t msgType) :
37     MctpAsioEndpoint{MCTP_ADDR_ANY, msgType}
38 {}
39 
eid() const40 std::optional<uint8_t> MctpAsioEndpoint::eid() const
41 {
42     const struct sockaddr_mctp* sock = getSockAddr();
43     if (sock == nullptr)
44     {
45         return std::nullopt;
46     }
47     return sock->smctp_addr.s_addr;
48 }
49 
type() const50 std::optional<uint8_t> MctpAsioEndpoint::type() const
51 {
52     const struct sockaddr_mctp* sock = getSockAddr();
53     if (sock == nullptr)
54     {
55         return std::nullopt;
56     }
57     return sock->smctp_type;
58 }
59 
getSockAddr() const60 const struct sockaddr_mctp* MctpAsioEndpoint::getSockAddr() const
61 {
62     if (endpoint.size() < sizeof(struct sockaddr_mctp))
63     {
64         lg2::error("MctpRequester: Received endpoint is too small?");
65         return nullptr;
66     }
67 
68     return std::bit_cast<struct sockaddr_mctp*>(endpoint.data());
69 }
70