1
2
3
4
5
6
7
8
9
10
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <errno.h>
16
17#include <linux/tipc_netlink.h>
18#include <linux/genetlink.h>
19
20#include "cmdl.h"
21#include "msg.h"
22#include "media.h"
23
24static int media_list_cb(const struct nlmsghdr *nlh, void *data)
25{
26 struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
27 struct nlattr *info[TIPC_NLA_MAX + 1] = {};
28 struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {};
29
30 mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
31 if (!info[TIPC_NLA_MEDIA])
32 return MNL_CB_ERROR;
33
34 mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs);
35 if (!attrs[TIPC_NLA_MEDIA_NAME])
36 return MNL_CB_ERROR;
37
38 printf("%s\n", mnl_attr_get_str(attrs[TIPC_NLA_MEDIA_NAME]));
39
40 return MNL_CB_OK;
41}
42
43static int cmd_media_list(struct nlmsghdr *nlh, const struct cmd *cmd,
44 struct cmdl *cmdl, void *data)
45{
46 if (help_flag) {
47 fprintf(stderr, "Usage: %s media list\n", cmdl->argv[0]);
48 return -EINVAL;
49 }
50
51 nlh = msg_init(TIPC_NL_MEDIA_GET);
52 if (!nlh) {
53 fprintf(stderr, "error, message initialisation failed\n");
54 return -1;
55 }
56
57 return msg_dumpit(nlh, media_list_cb, NULL);
58}
59
60static int media_get_cb(const struct nlmsghdr *nlh, void *data)
61{
62 int *prop = data;
63 struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
64 struct nlattr *info[TIPC_NLA_MAX + 1] = {};
65 struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {};
66 struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {};
67
68 mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
69 if (!info[TIPC_NLA_MEDIA])
70 return MNL_CB_ERROR;
71
72 mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs);
73 if (!attrs[TIPC_NLA_MEDIA_PROP])
74 return MNL_CB_ERROR;
75
76 mnl_attr_parse_nested(attrs[TIPC_NLA_MEDIA_PROP], parse_attrs, props);
77 if (!props[*prop])
78 return MNL_CB_ERROR;
79
80 printf("%u\n", mnl_attr_get_u32(props[*prop]));
81
82 return MNL_CB_OK;
83}
84
85static int cmd_media_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
86 struct cmdl *cmdl, void *data)
87{
88 int prop;
89 struct nlattr *nest;
90 struct opt *opt;
91 struct opt opts[] = {
92 { "media", OPT_KEYVAL, NULL },
93 { NULL }
94 };
95
96 if (strcmp(cmd->cmd, "priority") == 0)
97 prop = TIPC_NLA_PROP_PRIO;
98 else if ((strcmp(cmd->cmd, "tolerance") == 0))
99 prop = TIPC_NLA_PROP_TOL;
100 else if ((strcmp(cmd->cmd, "window") == 0))
101 prop = TIPC_NLA_PROP_WIN;
102 else if ((strcmp(cmd->cmd, "mtu") == 0))
103 prop = TIPC_NLA_PROP_MTU;
104 else
105 return -EINVAL;
106
107 if (help_flag) {
108 (cmd->help)(cmdl);
109 return -EINVAL;
110 }
111
112 if (parse_opts(opts, cmdl) < 0)
113 return -EINVAL;
114
115 nlh = msg_init(TIPC_NL_MEDIA_GET);
116 if (!nlh) {
117 fprintf(stderr, "error, message initialisation failed\n");
118 return -1;
119 }
120
121 if (!(opt = get_opt(opts, "media"))) {
122 fprintf(stderr, "error, missing media\n");
123 return -EINVAL;
124 }
125
126 if ((prop == TIPC_NLA_PROP_MTU) &&
127 (strcmp(opt->val, "udp"))) {
128 fprintf(stderr, "error, not supported for media\n");
129 return -EINVAL;
130 }
131 nest = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA);
132 mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val);
133 mnl_attr_nest_end(nlh, nest);
134
135 return msg_doit(nlh, media_get_cb, &prop);
136}
137
138static void cmd_media_get_help(struct cmdl *cmdl)
139{
140 fprintf(stderr, "Usage: %s media get PPROPERTY media MEDIA\n\n"
141 "PROPERTIES\n"
142 " tolerance - Get media tolerance\n"
143 " priority - Get media priority\n"
144 " window - Get media window\n"
145 " mtu - Get media mtu\n",
146 cmdl->argv[0]);
147}
148
149static int cmd_media_get(struct nlmsghdr *nlh, const struct cmd *cmd,
150 struct cmdl *cmdl, void *data)
151{
152 const struct cmd cmds[] = {
153 { "priority", cmd_media_get_prop, cmd_media_get_help },
154 { "tolerance", cmd_media_get_prop, cmd_media_get_help },
155 { "window", cmd_media_get_prop, cmd_media_get_help },
156 { "mtu", cmd_media_get_prop, cmd_media_get_help },
157 { NULL }
158 };
159
160 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
161}
162
163static void cmd_media_set_help(struct cmdl *cmdl)
164{
165 fprintf(stderr, "Usage: %s media set PPROPERTY media MEDIA\n\n"
166 "PROPERTIES\n"
167 " tolerance TOLERANCE - Set media tolerance\n"
168 " priority PRIORITY - Set media priority\n"
169 " window WINDOW - Set media window\n"
170 " mtu MTU - Set media mtu\n",
171 cmdl->argv[0]);
172}
173
174static int cmd_media_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
175 struct cmdl *cmdl, void *data)
176{
177 int val;
178 int prop;
179 struct nlattr *props;
180 struct nlattr *attrs;
181 struct opt *opt;
182 struct opt opts[] = {
183 { "media", OPT_KEYVAL, NULL },
184 { NULL }
185 };
186
187 if (strcmp(cmd->cmd, "priority") == 0)
188 prop = TIPC_NLA_PROP_PRIO;
189 else if ((strcmp(cmd->cmd, "tolerance") == 0))
190 prop = TIPC_NLA_PROP_TOL;
191 else if ((strcmp(cmd->cmd, "window") == 0))
192 prop = TIPC_NLA_PROP_WIN;
193 else if ((strcmp(cmd->cmd, "mtu") == 0))
194 prop = TIPC_NLA_PROP_MTU;
195 else
196 return -EINVAL;
197
198 if (help_flag) {
199 (cmd->help)(cmdl);
200 return -EINVAL;
201 }
202
203 if (cmdl->optind >= cmdl->argc) {
204 fprintf(stderr, "error, missing value\n");
205 return -EINVAL;
206 }
207 val = atoi(shift_cmdl(cmdl));
208
209 if (parse_opts(opts, cmdl) < 0)
210 return -EINVAL;
211
212 nlh = msg_init(TIPC_NL_MEDIA_SET);
213 if (!nlh) {
214 fprintf(stderr, "error, message initialisation failed\n");
215 return -1;
216 }
217 attrs = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA);
218
219 if (!(opt = get_opt(opts, "media"))) {
220 fprintf(stderr, "error, missing media\n");
221 return -EINVAL;
222 }
223
224 if ((prop == TIPC_NLA_PROP_MTU) &&
225 (strcmp(opt->val, "udp"))) {
226 fprintf(stderr, "error, not supported for media\n");
227 return -EINVAL;
228 }
229 mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val);
230
231 props = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA_PROP);
232 mnl_attr_put_u32(nlh, prop, val);
233 mnl_attr_nest_end(nlh, props);
234
235 mnl_attr_nest_end(nlh, attrs);
236
237 return msg_doit(nlh, NULL, NULL);
238}
239
240static int cmd_media_set(struct nlmsghdr *nlh, const struct cmd *cmd,
241 struct cmdl *cmdl, void *data)
242{
243 const struct cmd cmds[] = {
244 { "priority", cmd_media_set_prop, cmd_media_set_help },
245 { "tolerance", cmd_media_set_prop, cmd_media_set_help },
246 { "window", cmd_media_set_prop, cmd_media_set_help },
247 { "mtu", cmd_media_set_prop, cmd_media_set_help },
248 { NULL }
249 };
250
251 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
252}
253
254void cmd_media_help(struct cmdl *cmdl)
255{
256 fprintf(stderr,
257 "Usage: %s media COMMAND [ARGS] ...\n"
258 "\n"
259 "Commands:\n"
260 " list - List active media types\n"
261 " get - Get various media properties\n"
262 " set - Set various media properties\n",
263 cmdl->argv[0]);
264}
265
266int cmd_media(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
267 void *data)
268{
269 const struct cmd cmds[] = {
270 { "get", cmd_media_get, cmd_media_get_help },
271 { "list", cmd_media_list, NULL },
272 { "set", cmd_media_set, cmd_media_set_help },
273 { NULL }
274 };
275
276 return run_cmd(nlh, cmd, cmds, cmdl, NULL);
277}
278