summaryrefslogtreecommitdiffstats
path: root/examples/genl-family-get.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/genl-family-get.c')
-rw-r--r--examples/genl-family-get.c113
1 files changed, 105 insertions, 8 deletions
diff --git a/examples/genl-family-get.c b/examples/genl-family-get.c
index 3e741cb..00f601c 100644
--- a/examples/genl-family-get.c
+++ b/examples/genl-family-get.c
@@ -5,15 +5,43 @@
#include <libmnl/libmnl.h>
#include <linux/genetlink.h>
+static int parse_mc_grps_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, CTRL_ATTR_MCAST_GRP_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case CTRL_ATTR_MCAST_GRP_ID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_MCAST_GRP_NAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static void parse_genl_mc_grps(struct nlattr *nested)
{
struct nlattr *pos;
int len;
- mnl_attr_for_each_nested(pos, nested, len) {
- struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1];
+ mnl_attr_for_each_nested(pos, nested) {
+ struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1] = {};
- mnl_attr_parse_nested(pos, tb, CTRL_ATTR_MCAST_GRP_MAX);
+ mnl_attr_parse_nested(pos, parse_mc_grps_cb, tb);
if (tb[CTRL_ATTR_MCAST_GRP_ID]) {
printf("id-0x%x ",
mnl_attr_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]));
@@ -26,15 +54,41 @@ static void parse_genl_mc_grps(struct nlattr *nested)
}
}
+static int parse_family_ops_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, CTRL_ATTR_OP_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case CTRL_ATTR_OP_ID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_OP_MAX:
+ break;
+ default:
+ return MNL_CB_OK;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static void parse_genl_family_ops(struct nlattr *nested)
{
struct nlattr *pos;
int len;
- mnl_attr_for_each_nested(pos, nested, len) {
- struct nlattr *tb[CTRL_ATTR_OP_MAX+1];
+ mnl_attr_for_each_nested(pos, nested) {
+ struct nlattr *tb[CTRL_ATTR_OP_MAX+1] = {};
- mnl_attr_parse_nested(pos, tb, CTRL_ATTR_OP_MAX);
+ mnl_attr_parse_nested(pos, parse_family_ops_cb, tb);
if (tb[CTRL_ATTR_OP_ID]) {
printf("id-0x%x ",
mnl_attr_get_u32(tb[CTRL_ATTR_OP_ID]));
@@ -46,12 +100,55 @@ static void parse_genl_family_ops(struct nlattr *nested)
}
}
+static int data_attr_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = (const struct nlattr **)data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_invalid(attr, CTRL_ATTR_MAX) < 0) {
+ perror("mnl_attr_type_invalid");
+ return MNL_CB_ERROR;
+ }
+
+ switch(type) {
+ case CTRL_ATTR_FAMILY_NAME:
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_FAMILY_ID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U16) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_VERSION:
+ case CTRL_ATTR_HDRSIZE:
+ case CTRL_ATTR_MAXATTR:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case CTRL_ATTR_OPS:
+ case CTRL_ATTR_MCAST_GROUPS:
+ if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
static int data_cb(const struct nlmsghdr *nlh, void *data)
{
- struct nlattr *tb[CTRL_ATTR_MAX+1];
+ struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
struct genlmsghdr *genl = mnl_nlmsg_get_data(nlh);
- mnl_attr_parse_at_offset(nlh, sizeof(*genl), tb, CTRL_ATTR_MAX);
+ mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb);
if (tb[CTRL_ATTR_FAMILY_NAME]) {
printf("name=%s\t",
mnl_attr_get_str(tb[CTRL_ATTR_FAMILY_NAME]));