_cleanup_(genl_family_freep) GenericNetlinkFamily *f = NULL;
const char *family_name;
+ uint8_t cmd;
int r;
assert(nl);
if (!streq(family_name, CTRL_GENL_NAME))
return -EINVAL;
+ r = sd_genl_message_get_command(nl, message, &cmd);
+ if (r < 0)
+ return r;
+
+ if (cmd != CTRL_CMD_NEWFAMILY)
+ return -EINVAL;
+
r = sd_netlink_message_read_u16(message, CTRL_ATTR_FAMILY_ID, &f->id);
if (r < 0)
return r;
return 0;
}
+int sd_genl_message_get_command(sd_netlink *nl, sd_netlink_message *m, uint8_t *ret) {
+ struct genlmsghdr *h;
+ uint16_t nlmsg_type;
+ size_t size;
+ int r;
+
+ assert_return(nl, -EINVAL);
+ assert_return(nl->protocol == NETLINK_GENERIC, -EINVAL);
+ assert_return(m, -EINVAL);
+ assert_return(m->protocol == NETLINK_GENERIC, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(ret, -EINVAL);
+
+ r = sd_netlink_message_get_type(m, &nlmsg_type);
+ if (r < 0)
+ return r;
+
+ r = genl_get_type_system_and_header_size(nl, nlmsg_type, NULL, &size);
+ if (r < 0)
+ return r;
+
+ if (m->hdr->nlmsg_len < NLMSG_LENGTH(size))
+ return -EBADMSG;
+
+ h = NLMSG_DATA(m->hdr);
+
+ *ret = h->cmd;
+ return 0;
+}
+
int sd_genl_socket_open(sd_netlink **ret) {
return netlink_open_family(ret, NETLINK_GENERIC);
}
_cleanup_(sd_netlink_unrefp) sd_netlink *genl = NULL;
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
const char *name;
+ uint8_t cmd;
log_debug("/* %s */", __func__);
assert_se(sd_genl_message_new(genl, CTRL_GENL_NAME, CTRL_CMD_GETFAMILY, &m) >= 0);
assert_se(sd_genl_message_get_family_name(genl, m, &name) >= 0);
assert_se(streq(name, CTRL_GENL_NAME));
+ assert_se(sd_genl_message_get_command(genl, m, &cmd) >= 0);
+ assert_se(cmd == CTRL_CMD_GETFAMILY);
m = sd_netlink_message_unref(m);
assert_se(sd_genl_message_new(genl, "should-not-exist", CTRL_CMD_GETFAMILY, &m) < 0);
int sd_genl_socket_open(sd_netlink **ret);
int sd_genl_message_new(sd_netlink *genl, const char *family_name, uint8_t cmd, sd_netlink_message **ret);
int sd_genl_message_get_family_name(sd_netlink *genl, sd_netlink_message *m, const char **ret);
+int sd_genl_message_get_command(sd_netlink *genl, sd_netlink_message *m, uint8_t *ret);
/* slot */
sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *slot);