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 const T * getPayload() const noexcept
Copyright (c) 2011-2015 Regents of the University of California.
constexpr size_t getAttributeValueLength(const T *attr)
NetlinkMessageAttributes(const T *begin, size_t length) noexcept
const size_t ADDR_LEN
Octets in one Ethernet address.
const nlmsghdr & operator *() const noexcept
constexpr uint16_t getAttributeType(const T *attr)
NetlinkMessage getNext() const noexcept
size_t size() const noexcept
import common constructs for ndn-cxx library internal use
optional< U > getAttributeByType(uint16_t attrType) const
constexpr size_t getAttributeLength(const T *attr)
bool isValid() const noexcept
constexpr size_t getAttributeLengthAligned(const T *attr)
NetlinkMessage(const uint8_t *buf, size_t buflen) noexcept
const uint8_t * getAttributeValue(const T *attr)
const nullopt_t nullopt((nullopt_t::init()))
const nlmsghdr * operator->() const noexcept
NetlinkMessageAttributes< AttributeT > getAttributes(const PayloadT *p) const noexcept