Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58a92454 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I56edff81,I6839a899

* changes:
  Print error names instead of numbers
  Implement NL80211 protocol printer
parents 418390cf 9ab67258
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ cc_library_static {
        "protocols/generic/Generic.cpp",
        "protocols/generic/GenericMessageBase.cpp",
        "protocols/generic/Unknown.cpp",
        "protocols/generic/families/Nl80211.cpp",
        "protocols/route/Link.cpp",
        "protocols/route/Route.cpp",
        "protocols/route/structs.cpp",
+31 −9
Original line number Diff line number Diff line
@@ -51,24 +51,24 @@ static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags, protocols::M
    printFlag(NLM_F_DUMP_FILTERED, "DUMP_FILTERED");

    switch (genre) {
        case protocols::MessageGenre::UNKNOWN:
        case protocols::MessageGenre::Unknown:
            break;
        case protocols::MessageGenre::GET:
        case protocols::MessageGenre::Get:
            printFlag(NLM_F_DUMP, "DUMP");  // ROOT | MATCH
            printFlag(NLM_F_ROOT, "ROOT");
            printFlag(NLM_F_MATCH, "MATCH");
            printFlag(NLM_F_ATOMIC, "ATOMIC");
            break;
        case protocols::MessageGenre::NEW:
        case protocols::MessageGenre::New:
            printFlag(NLM_F_REPLACE, "REPLACE");
            printFlag(NLM_F_EXCL, "EXCL");
            printFlag(NLM_F_CREATE, "CREATE");
            printFlag(NLM_F_APPEND, "APPEND");
            break;
        case protocols::MessageGenre::DELETE:
        case protocols::MessageGenre::Delete:
            printFlag(NLM_F_NONREC, "NONREC");
            break;
        case protocols::MessageGenre::ACK:
        case protocols::MessageGenre::Ack:
            printFlag(NLM_F_CAPPED, "CAPPED");
            printFlag(NLM_F_ACK_TLVS, "ACK_TLVS");
            break;
@@ -99,11 +99,25 @@ static void toStream(std::stringstream& ss, const Buffer<uint8_t> data) {
static void toStream(std::stringstream& ss, const Buffer<nlattr> attr,
                     const protocols::AttributeMap& attrMap) {
    using DataType = protocols::AttributeDefinition::DataType;
    using Flags = protocols::AttributeDefinition::Flags;
    const auto attrtype = attrMap[attr->nla_type];

    ss << attrtype.name << ": ";
    ss << attrtype.name;

    if (attrtype.dataType == DataType::Flag && attr.data<uint8_t>().getRaw().len() == 0) return;
    ss << ": ";

    if (attrtype.flags == Flags::Verbose) {
        const auto raw = attr.data<uint8_t>();
        ss << "{len=" << raw.getRaw().len();
        ss << ", crc=" << std::hex << std::setw(4) << crc16(raw) << std::dec;
        ss << "}";
        return;
    }

    switch (attrtype.dataType) {
        case DataType::Raw:
        case DataType::Flag:
            toStream(ss, attr.data<uint8_t>());
            break;
        case DataType::Nested: {
@@ -117,13 +131,19 @@ static void toStream(std::stringstream& ss, const Buffer<nlattr> attr,
            ss << '}';
            break;
        }
        case DataType::StringNul:
        case DataType::String: {
            const auto str = attr.data<char>().getRaw();
            ss << '"' << printableOnly({str.ptr(), str.len()}) << '"';
            auto len = str.len();
            if (attrtype.dataType == DataType::StringNul && len > 0 && str.ptr()[len - 1] == '\0') {
                len--;
            }

            ss << '"' << printableOnly({str.ptr(), len}) << '"';
            break;
        }
        case DataType::Uint:
            ss << attr.data<uint32_t>().copyFirst();
            ss << attr.data<uint64_t>().copyFirst();
            break;
        case DataType::Struct: {
            const auto structToStream =
@@ -147,10 +167,12 @@ std::string toString(const Buffer<nlmsghdr> hdr, int protocol, bool printPayload
    }
    protocols::NetlinkProtocol& protocolDescr = *protocolMaybe;

    const auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type);
    auto msgDescMaybe = protocolDescr.getMessageDescriptor(hdr->nlmsg_type);
    const auto msgDetails =
            protocols::MessageDescriptor::getMessageDetails(msgDescMaybe, hdr->nlmsg_type);

    if (msgDescMaybe.has_value()) msgDescMaybe->get().track(hdr);

    ss << "nlmsg{" << protocolDescr.getName() << " ";

    ss << "hdr={";
+5 −3
Original line number Diff line number Diff line
@@ -56,15 +56,17 @@ const AttributeMap& MessageDescriptor::getAttributeMap() const {

MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(nlmsgtype_t msgtype) const {
    const auto it = mMessageDetails.find(msgtype);
    if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::UNKNOWN};
    if (it == mMessageDetails.end()) return {std::to_string(msgtype), MessageGenre::Unknown};
    return it->second;
}

MessageDescriptor::MessageDetails MessageDescriptor::getMessageDetails(
        const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe,
        const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe,
        nlmsgtype_t msgtype) {
    if (msgDescMaybe.has_value()) return msgDescMaybe->get().getMessageDetails(msgtype);
    return {std::to_string(msgtype), protocols::MessageGenre::UNKNOWN};
    return {std::to_string(msgtype), protocols::MessageGenre::Unknown};
}

void MessageDescriptor::track(const Buffer<nlmsghdr> /* hdr */) {}

}  // namespace android::nl::protocols
+60 −6
Original line number Diff line number Diff line
@@ -54,17 +54,64 @@ class AttributeMap : private std::map<std::optional<nlattrtype_t>, AttributeDefi
 */
struct AttributeDefinition {
    enum class DataType : uint8_t {
        /**
         * Binary blob (or attribute of unknown type).
         */
        Raw,

        /**
         * Nested attribute (with or without NLA_F_NESTED).
         */
        Nested,

        /**
         * Non-null terminated string.
         *
         * The length of the string is determined by the size of an attribute.
         */
        String,

        /**
         * Null terminated string.
         */
        StringNul,

        /**
         * Unsigned integer of size 8, 16, 32 or 64 bits.
         */
        Uint,

        /**
         * Structure which printer is defined in ops ToStream variant.
         */
        Struct,

        /**
         * Flag attribute.
         *
         * The attribute doesn't have any contents. The flag is set when the attribute is present,
         * it's not when it's absent from attribute list.
         */
        Flag,
    };
    enum class Flags : uint8_t {
        Verbose = (1 << 0),
    };
    using ToStream = std::function<void(std::stringstream& ss, const Buffer<nlattr> attr)>;

    std::string name;
    DataType dataType = DataType::Raw;
    std::variant<AttributeMap, ToStream> ops = AttributeMap{};

    /**
     * Attribute flags.
     *
     * It's not really a bitmask flag set (since you are not supposed to compare enum class by
     * bitmask), but std::set<Flags> bumps compile time from 16s to 3m. Let's leave it as-is for
     * now and revisit if we get some flags that can be used in pairs. When it happens, review all
     * uses of the flags field to include the "&" operator and not "==".
     */
    Flags flags = {};
};

/**
@@ -74,11 +121,11 @@ struct AttributeDefinition {
 * section in linux/netlink.h.
 */
enum class MessageGenre {
    UNKNOWN,
    GET,
    NEW,
    DELETE,
    ACK,
    Unknown,
    Get,
    New,
    Delete,
    Ack,
};

/**
@@ -103,8 +150,15 @@ class MessageDescriptor {
    MessageDetails getMessageDetails(nlmsgtype_t msgtype) const;
    virtual void dataToStream(std::stringstream& ss, const Buffer<nlmsghdr> hdr) const = 0;

    /**
     * Message tracking for stateful protocols (such as NETLINK_GENERIC).
     *
     * \param hdr Message to track
     */
    virtual void track(const Buffer<nlmsghdr> hdr);

    static MessageDetails getMessageDetails(
            const std::optional<std::reference_wrapper<const MessageDescriptor>>& msgDescMaybe,
            const std::optional<std::reference_wrapper<MessageDescriptor>>& msgDescMaybe,
            nlmsgtype_t msgtype);

  protected:
+2 −2
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ const std::string& NetlinkProtocol::getName() const {
    return mName;
}

const std::optional<std::reference_wrapper<const MessageDescriptor>>
const std::optional<std::reference_wrapper<MessageDescriptor>>
NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) {
    if (mMessageDescrs.count(nlmsg_type) == 0) return std::nullopt;
    return *mMessageDescrs.find(nlmsg_type)->second;
@@ -41,7 +41,7 @@ NetlinkProtocol::getMessageDescriptor(nlmsgtype_t nlmsg_type) {
NetlinkProtocol::MessageDescriptorMap NetlinkProtocol::toMap(
        const NetlinkProtocol::MessageDescriptorList& descrs, int protocol) {
    MessageDescriptorMap map;
    for (const auto& descr : descrs) {
    for (auto& descr : descrs) {
        for (const auto& [mtype, mdet] : descr->getMessageDetailsMap()) {
            map.emplace(mtype, descr);
        }
Loading