Esempio n. 1
0
int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) {
        _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL;
        const NLType *nl_type;
        size_t size;
        int r;

        r = type_system_get_type(&type_system_root, &nl_type, type);
        if (r < 0)
                return r;

        if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
                return -EINVAL;

        r = message_new_empty(rtnl, &m);
        if (r < 0)
                return r;

        size = NLMSG_SPACE(type_get_size(nl_type));

        assert(size >= sizeof(struct nlmsghdr));
        m->hdr = malloc0(size);
        if (!m->hdr)
                return -ENOMEM;

        m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;

        type_get_type_system(nl_type, &m->containers[0].type_system);
        m->hdr->nlmsg_len = size;
        m->hdr->nlmsg_type = type;

        *ret = m;
        m = NULL;

        return 0;
}
static int genl_message_new(sd_netlink *nl, sd_genl_family family, uint16_t nlmsg_type, uint8_t cmd, sd_netlink_message **ret) {
        int r;
        struct genlmsghdr *genl;
        const NLType *genl_cmd_type, *nl_type;
        const NLTypeSystem *type_system;
        size_t size;
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;

        assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);

        r = type_system_get_type(&genl_family_type_system_root, &genl_cmd_type, family);
        if (r < 0)
                return r;

        r = message_new_empty(nl, &m);
        if (r < 0)
                return r;

        size = NLMSG_SPACE(sizeof(struct genlmsghdr));
        m->hdr = malloc0(size);
        if (!m->hdr)
                return -ENOMEM;

        m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;

        type_get_type_system(genl_cmd_type, &type_system);

        r = type_system_get_type(type_system, &nl_type, cmd);
        if (r < 0)
                return r;

        m->hdr->nlmsg_len = size;
        m->hdr->nlmsg_type = nlmsg_type;

        type_get_type_system(nl_type, &m->containers[0].type_system);
        genl = NLMSG_DATA(m->hdr);
        genl->cmd = cmd;
        genl->version = genl_families[family].version;

        *ret = TAKE_PTR(m);

        return 0;
}
Esempio n. 3
0
int sd_netlink_message_rewind(sd_netlink_message *m) {
        const NLType *nl_type;
        uint16_t type;
        size_t size;
        unsigned i;
        int r;

        assert_return(m, -EINVAL);

        /* don't allow appending to message once parsed */
        if (!m->sealed)
                rtnl_message_seal(m);

        for (i = 1; i <= m->n_containers; i++)
                m->containers[i].attributes = mfree(m->containers[i].attributes);

        m->n_containers = 0;

        if (m->containers[0].attributes)
                /* top-level attributes have already been parsed */
                return 0;

        assert(m->hdr);

        r = type_system_get_type(&type_system_root, &nl_type, m->hdr->nlmsg_type);
        if (r < 0)
                return r;

        type = type_get_type(nl_type);
        size = type_get_size(nl_type);

        if (type == NETLINK_TYPE_NESTED) {
                const NLTypeSystem *type_system;

                type_get_type_system(nl_type, &type_system);

                m->containers[0].type_system = type_system;

                r = netlink_container_parse(m,
                                            &m->containers[m->n_containers],
                                            type_system_get_count(type_system),
                                            (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)),
                                            NLMSG_PAYLOAD(m->hdr, size));
                if (r < 0)
                        return r;
        }

        return 0;
}