7 #include <libmnl/libmnl.h>
8 #include <linux/genetlink.h>
10 static int parse_mc_grps_cb(
const struct nlattr *attr,
void *data)
12 const struct nlattr **tb = data;
20 case CTRL_ATTR_MCAST_GRP_ID:
22 perror(
"mnl_attr_validate");
26 case CTRL_ATTR_MCAST_GRP_NAME:
28 perror(
"mnl_attr_validate");
37 static void parse_genl_mc_grps(
struct nlattr *nested)
41 mnl_attr_for_each_nested(pos, nested) {
42 struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1] = {};
45 if (tb[CTRL_ATTR_MCAST_GRP_ID]) {
49 if (tb[CTRL_ATTR_MCAST_GRP_NAME]) {
57 static int parse_family_ops_cb(
const struct nlattr *attr,
void *data)
59 const struct nlattr **tb = data;
68 perror(
"mnl_attr_validate");
72 case CTRL_ATTR_OP_MAX:
81 static void parse_genl_family_ops(
struct nlattr *nested)
85 mnl_attr_for_each_nested(pos, nested) {
86 struct nlattr *tb[CTRL_ATTR_OP_MAX+1] = {};
89 if (tb[CTRL_ATTR_OP_ID]) {
93 if (tb[CTRL_ATTR_OP_MAX]) {
100 static int data_attr_cb(
const struct nlattr *attr,
void *data)
102 const struct nlattr **tb = data;
109 case CTRL_ATTR_FAMILY_NAME:
111 perror(
"mnl_attr_validate");
115 case CTRL_ATTR_FAMILY_ID:
117 perror(
"mnl_attr_validate");
121 case CTRL_ATTR_VERSION:
122 case CTRL_ATTR_HDRSIZE:
123 case CTRL_ATTR_MAXATTR:
125 perror(
"mnl_attr_validate");
130 case CTRL_ATTR_MCAST_GROUPS:
132 perror(
"mnl_attr_validate");
141 static int data_cb(
const struct nlmsghdr *nlh,
void *data)
143 struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
147 if (tb[CTRL_ATTR_FAMILY_NAME]) {
151 if (tb[CTRL_ATTR_FAMILY_ID]) {
155 if (tb[CTRL_ATTR_VERSION]) {
156 printf(
"version=%u\t",
159 if (tb[CTRL_ATTR_HDRSIZE]) {
160 printf(
"hdrsize=%u\t",
163 if (tb[CTRL_ATTR_MAXATTR]) {
164 printf(
"maxattr=%u\t",
168 if (tb[CTRL_ATTR_OPS]) {
170 parse_genl_family_ops(tb[CTRL_ATTR_OPS]);
172 if (tb[CTRL_ATTR_MCAST_GROUPS]) {
174 parse_genl_mc_grps(tb[CTRL_ATTR_MCAST_GROUPS]);
180 int main(
int argc,
char *argv[])
183 char buf[MNL_SOCKET_BUFFER_SIZE];
184 struct nlmsghdr *nlh;
185 struct genlmsghdr *genl;
187 unsigned int seq, portid;
190 printf(
"%s [family name]\n", argv[0]);
195 nlh->nlmsg_type = GENL_ID_CTRL;
196 nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
197 nlh->nlmsg_seq = seq = time(NULL);
200 genl->cmd = CTRL_CMD_GETFAMILY;
207 nlh->nlmsg_flags |= NLM_F_DUMP;
211 perror(
"mnl_socket_open");
216 perror(
"mnl_socket_bind");
222 perror(
"mnl_socket_send");
228 ret =
mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);