summaryrefslogtreecommitdiffstats
path: root/tipc/media.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tipc/media.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/tipc/media.c b/tipc/media.c
new file mode 100644
index 0000000..a3fec68
--- /dev/null
+++ b/tipc/media.c
@@ -0,0 +1,277 @@
+/*
+ * media.c TIPC link functionality.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Richard Alpe <richard.alpe@ericsson.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <linux/tipc_netlink.h>
+#include <linux/genetlink.h>
+
+#include "cmdl.h"
+#include "msg.h"
+#include "media.h"
+
+static int media_list_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+ struct nlattr *info[TIPC_NLA_MAX + 1] = {};
+ struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {};
+
+ mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+ if (!info[TIPC_NLA_MEDIA])
+ return MNL_CB_ERROR;
+
+ mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs);
+ if (!attrs[TIPC_NLA_MEDIA_NAME])
+ return MNL_CB_ERROR;
+
+ printf("%s\n", mnl_attr_get_str(attrs[TIPC_NLA_MEDIA_NAME]));
+
+ return MNL_CB_OK;
+}
+
+static int cmd_media_list(struct nlmsghdr *nlh, const struct cmd *cmd,
+ struct cmdl *cmdl, void *data)
+{
+ if (help_flag) {
+ fprintf(stderr, "Usage: %s media list\n", cmdl->argv[0]);
+ return -EINVAL;
+ }
+
+ nlh = msg_init(TIPC_NL_MEDIA_GET);
+ if (!nlh) {
+ fprintf(stderr, "error, message initialisation failed\n");
+ return -1;
+ }
+
+ return msg_dumpit(nlh, media_list_cb, NULL);
+}
+
+static int media_get_cb(const struct nlmsghdr *nlh, void *data)
+{
+ int *prop = data;
+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+ struct nlattr *info[TIPC_NLA_MAX + 1] = {};
+ struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {};
+ struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {};
+
+ mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+ if (!info[TIPC_NLA_MEDIA])
+ return MNL_CB_ERROR;
+
+ mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs);
+ if (!attrs[TIPC_NLA_MEDIA_PROP])
+ return MNL_CB_ERROR;
+
+ mnl_attr_parse_nested(attrs[TIPC_NLA_MEDIA_PROP], parse_attrs, props);
+ if (!props[*prop])
+ return MNL_CB_ERROR;
+
+ printf("%u\n", mnl_attr_get_u32(props[*prop]));
+
+ return MNL_CB_OK;
+}
+
+static int cmd_media_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
+ struct cmdl *cmdl, void *data)
+{
+ int prop;
+ struct nlattr *nest;
+ struct opt *opt;
+ struct opt opts[] = {
+ { "media", OPT_KEYVAL, NULL },
+ { NULL }
+ };
+
+ if (strcmp(cmd->cmd, "priority") == 0)
+ prop = TIPC_NLA_PROP_PRIO;
+ else if ((strcmp(cmd->cmd, "tolerance") == 0))
+ prop = TIPC_NLA_PROP_TOL;
+ else if ((strcmp(cmd->cmd, "window") == 0))
+ prop = TIPC_NLA_PROP_WIN;
+ else if ((strcmp(cmd->cmd, "mtu") == 0))
+ prop = TIPC_NLA_PROP_MTU;
+ else
+ return -EINVAL;
+
+ if (help_flag) {
+ (cmd->help)(cmdl);
+ return -EINVAL;
+ }
+
+ if (parse_opts(opts, cmdl) < 0)
+ return -EINVAL;
+
+ nlh = msg_init(TIPC_NL_MEDIA_GET);
+ if (!nlh) {
+ fprintf(stderr, "error, message initialisation failed\n");
+ return -1;
+ }
+
+ if (!(opt = get_opt(opts, "media"))) {
+ fprintf(stderr, "error, missing media\n");
+ return -EINVAL;
+ }
+
+ if ((prop == TIPC_NLA_PROP_MTU) &&
+ (strcmp(opt->val, "udp"))) {
+ fprintf(stderr, "error, not supported for media\n");
+ return -EINVAL;
+ }
+ nest = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA);
+ mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val);
+ mnl_attr_nest_end(nlh, nest);
+
+ return msg_doit(nlh, media_get_cb, &prop);
+}
+
+static void cmd_media_get_help(struct cmdl *cmdl)
+{
+ fprintf(stderr, "Usage: %s media get PPROPERTY media MEDIA\n\n"
+ "PROPERTIES\n"
+ " tolerance - Get media tolerance\n"
+ " priority - Get media priority\n"
+ " window - Get media window\n"
+ " mtu - Get media mtu\n",
+ cmdl->argv[0]);
+}
+
+static int cmd_media_get(struct nlmsghdr *nlh, const struct cmd *cmd,
+ struct cmdl *cmdl, void *data)
+{
+ const struct cmd cmds[] = {
+ { "priority", cmd_media_get_prop, cmd_media_get_help },
+ { "tolerance", cmd_media_get_prop, cmd_media_get_help },
+ { "window", cmd_media_get_prop, cmd_media_get_help },
+ { "mtu", cmd_media_get_prop, cmd_media_get_help },
+ { NULL }
+ };
+
+ return run_cmd(nlh, cmd, cmds, cmdl, NULL);
+}
+
+static void cmd_media_set_help(struct cmdl *cmdl)
+{
+ fprintf(stderr, "Usage: %s media set PPROPERTY media MEDIA\n\n"
+ "PROPERTIES\n"
+ " tolerance TOLERANCE - Set media tolerance\n"
+ " priority PRIORITY - Set media priority\n"
+ " window WINDOW - Set media window\n"
+ " mtu MTU - Set media mtu\n",
+ cmdl->argv[0]);
+}
+
+static int cmd_media_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd,
+ struct cmdl *cmdl, void *data)
+{
+ int val;
+ int prop;
+ struct nlattr *props;
+ struct nlattr *attrs;
+ struct opt *opt;
+ struct opt opts[] = {
+ { "media", OPT_KEYVAL, NULL },
+ { NULL }
+ };
+
+ if (strcmp(cmd->cmd, "priority") == 0)
+ prop = TIPC_NLA_PROP_PRIO;
+ else if ((strcmp(cmd->cmd, "tolerance") == 0))
+ prop = TIPC_NLA_PROP_TOL;
+ else if ((strcmp(cmd->cmd, "window") == 0))
+ prop = TIPC_NLA_PROP_WIN;
+ else if ((strcmp(cmd->cmd, "mtu") == 0))
+ prop = TIPC_NLA_PROP_MTU;
+ else
+ return -EINVAL;
+
+ if (help_flag) {
+ (cmd->help)(cmdl);
+ return -EINVAL;
+ }
+
+ if (cmdl->optind >= cmdl->argc) {
+ fprintf(stderr, "error, missing value\n");
+ return -EINVAL;
+ }
+ val = atoi(shift_cmdl(cmdl));
+
+ if (parse_opts(opts, cmdl) < 0)
+ return -EINVAL;
+
+ nlh = msg_init(TIPC_NL_MEDIA_SET);
+ if (!nlh) {
+ fprintf(stderr, "error, message initialisation failed\n");
+ return -1;
+ }
+ attrs = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA);
+
+ if (!(opt = get_opt(opts, "media"))) {
+ fprintf(stderr, "error, missing media\n");
+ return -EINVAL;
+ }
+
+ if ((prop == TIPC_NLA_PROP_MTU) &&
+ (strcmp(opt->val, "udp"))) {
+ fprintf(stderr, "error, not supported for media\n");
+ return -EINVAL;
+ }
+ mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val);
+
+ props = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA_PROP);
+ mnl_attr_put_u32(nlh, prop, val);
+ mnl_attr_nest_end(nlh, props);
+
+ mnl_attr_nest_end(nlh, attrs);
+
+ return msg_doit(nlh, NULL, NULL);
+}
+
+static int cmd_media_set(struct nlmsghdr *nlh, const struct cmd *cmd,
+ struct cmdl *cmdl, void *data)
+{
+ const struct cmd cmds[] = {
+ { "priority", cmd_media_set_prop, cmd_media_set_help },
+ { "tolerance", cmd_media_set_prop, cmd_media_set_help },
+ { "window", cmd_media_set_prop, cmd_media_set_help },
+ { "mtu", cmd_media_set_prop, cmd_media_set_help },
+ { NULL }
+ };
+
+ return run_cmd(nlh, cmd, cmds, cmdl, NULL);
+}
+
+void cmd_media_help(struct cmdl *cmdl)
+{
+ fprintf(stderr,
+ "Usage: %s media COMMAND [ARGS] ...\n"
+ "\n"
+ "Commands:\n"
+ " list - List active media types\n"
+ " get - Get various media properties\n"
+ " set - Set various media properties\n",
+ cmdl->argv[0]);
+}
+
+int cmd_media(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
+ void *data)
+{
+ const struct cmd cmds[] = {
+ { "get", cmd_media_get, cmd_media_get_help },
+ { "list", cmd_media_list, NULL },
+ { "set", cmd_media_set, cmd_media_set_help },
+ { NULL }
+ };
+
+ return run_cmd(nlh, cmd, cmds, cmdl, NULL);
+}