24 #ifndef NDN_NET_NETLINK_MESSAGE_HPP
25 #define NDN_NET_NETLINK_MESSAGE_HPP
30 #ifndef NDN_CXX_HAVE_NETLINK
31 #error "This file should not be included ..."
34 #include <linux/netlink.h>
35 #include <linux/rtnetlink.h>
41 #include <boost/asio/ip/address.hpp>
72 return NLA_ALIGN(attr->nla_len);
79 return RTA_ALIGN(attr->rta_len);
90 return attr->nla_type & NLA_TYPE_MASK;
97 return attr->rta_type;
105 inline const uint8_t*
108 return reinterpret_cast<const uint8_t*
>(attr) + NLA_HDRLEN;
112 inline const uint8_t*
115 return reinterpret_cast<const uint8_t*
>(RTA_DATA(
const_cast<rtattr*
>(attr)));
126 return attr->nla_len - NLA_HDRLEN;
133 return RTA_PAYLOAD(attr);
144 : m_msg(
reinterpret_cast<const nlmsghdr*
>(
buf))
147 BOOST_ASSERT(
buf !=
nullptr);
165 return NLMSG_OK(m_msg, m_length);
174 auto thisLen = NLMSG_ALIGN(m_msg->nlmsg_len);
175 return NetlinkMessage{
reinterpret_cast<const uint8_t*
>(m_msg) + thisLen, m_length - thisLen};
184 if (m_msg->nlmsg_len < NLMSG_LENGTH(
sizeof(T)))
187 return reinterpret_cast<const T*
>(NLMSG_DATA(
const_cast<nlmsghdr*
>(m_msg)));
190 template<
typename AttributeT,
typename PayloadT>
196 auto begin =
reinterpret_cast<const uint8_t*
>(p) + NLMSG_ALIGN(
sizeof(PayloadT));
197 auto length = NLMSG_PAYLOAD(m_msg,
sizeof(PayloadT));
202 const nlmsghdr* m_msg;
207 class NetlinkMessageAttributes
211 struct AttrValueTypeTag {};
217 for (; isAttrValid(begin, length); begin = getNextAttr(begin, length)) {
225 return m_attrs.size();
232 auto it = m_attrs.find(attrType);
233 if (it == m_attrs.end())
238 AttrValueTypeTag<U>{});
243 isAttrValid(
const T* attr,
size_t nBytesRemaining) noexcept
245 return attr !=
nullptr &&
246 nBytesRemaining >=
sizeof(T) &&
252 getNextAttr(
const T* attr,
size_t& nBytesRemaining) noexcept
255 if (len > nBytesRemaining)
258 nBytesRemaining -= len;
259 return reinterpret_cast<const T*
>(
reinterpret_cast<const uint8_t*
>(attr) + len);
262 template<
typename Integral>
263 static std::enable_if_t<std::is_integral<Integral>::value, optional<Integral>>
264 convertAttrValue(
const uint8_t* val,
size_t len, AttrValueTypeTag<Integral>)
266 if (len <
sizeof(Integral))
270 std::memcpy(&i, val,
sizeof(Integral));
274 static optional<std::string>
275 convertAttrValue(
const uint8_t* val,
size_t len, AttrValueTypeTag<std::string>)
277 auto str =
reinterpret_cast<const char*
>(val);
278 if (::strnlen(str, len) < len)
279 return std::string(str);
284 static optional<ethernet::Address>
285 convertAttrValue(
const uint8_t* val,
size_t len, AttrValueTypeTag<ethernet::Address>)
290 return ethernet::Address(val);
293 template<
typename IpAddress>
294 static std::enable_if_t<std::is_same<IpAddress, boost::asio::ip::address_v4>::value ||
295 std::is_same<IpAddress, boost::asio::ip::address_v6>::value, optional<IpAddress>>
296 convertAttrValue(
const uint8_t* val,
size_t len, AttrValueTypeTag<IpAddress>)
298 typename IpAddress::bytes_type bytes;
299 if (len < bytes.size())
302 std::copy_n(val, bytes.size(), bytes.begin());
303 return IpAddress(bytes);
307 std::map<uint16_t, const T*> m_attrs;
313 #endif // NDN_NET_NETLINK_MESSAGE_HPP