]> git.ipfire.org Git - thirdparty/iw.git/blame - genl.c
suppress flags on disabled channels
[thirdparty/iw.git] / genl.c
CommitLineData
2c61ba61
JB
1/*
2 * This ought to be provided by libnl
3 */
4
5#include <asm/errno.h>
6#include <netlink/genl/genl.h>
7#include <netlink/genl/family.h>
8#include <netlink/genl/ctrl.h>
9#include <netlink/msg.h>
10#include <netlink/attr.h>
11
656aa246
JB
12#include "iw.h"
13
2c61ba61
JB
14static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
15 void *arg)
16{
17 int *ret = arg;
18 *ret = err->error;
19 return NL_STOP;
20}
21
2c61ba61
JB
22static int ack_handler(struct nl_msg *msg, void *arg)
23{
24 int *ret = arg;
25 *ret = 0;
26 return NL_STOP;
27}
28
29struct handler_args {
30 const char *group;
31 int id;
32};
33
34static int family_handler(struct nl_msg *msg, void *arg)
35{
36 struct handler_args *grp = arg;
37 struct nlattr *tb[CTRL_ATTR_MAX + 1];
38 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
39 struct nlattr *mcgrp;
40 int rem_mcgrp;
41
42 nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
43 genlmsg_attrlen(gnlh, 0), NULL);
44
45 if (!tb[CTRL_ATTR_MCAST_GROUPS])
46 return NL_SKIP;
47
48 nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
49 struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
50
51 nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX,
52 nla_data(mcgrp), nla_len(mcgrp), NULL);
53
54 if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] ||
55 !tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID])
56 continue;
57 if (strncmp(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]),
58 grp->group, nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])))
59 continue;
60 grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
61 break;
62 }
63
64 return NL_SKIP;
65}
66
67int nl_get_multicast_id(struct nl_handle *handle, const char *family, const char *group)
68{
69 struct nl_msg *msg;
70 struct nl_cb *cb;
71 int ret, ctrlid;
72 struct handler_args grp = {
73 .group = group,
74 .id = -ENOENT,
75 };
76
77 msg = nlmsg_alloc();
78 if (!msg)
79 return -ENOMEM;
80
81 cb = nl_cb_alloc(NL_CB_DEFAULT);
82 if (!cb) {
83 ret = -ENOMEM;
84 goto out_fail_cb;
85 }
86
87 ctrlid = genl_ctrl_resolve(handle, "nlctrl");
88
89 genlmsg_put(msg, 0, 0, ctrlid, 0,
90 0, CTRL_CMD_GETFAMILY, 0);
91
92 ret = -ENOBUFS;
93 NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family);
94
95 ret = nl_send_auto_complete(handle, msg);
96 if (ret < 0)
97 goto out;
98
99 ret = 1;
100
101 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &ret);
2c61ba61
JB
102 nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &ret);
103 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, family_handler, &grp);
104
105 while (ret > 0)
106 nl_recvmsgs(handle, cb);
107
108 if (ret == 0)
109 ret = grp.id;
110 nla_put_failure:
111 out:
112 nl_cb_put(cb);
113 out_fail_cb:
114 nlmsg_free(msg);
115 return ret;
116}