1/*
2 * nametable.c	TIPC nametable functionality.
3 *
4 *		This program is free software; you can redistribute it and/or
5 *		modify it under the terms of the GNU General Public License
6 *		as published by the Free Software Foundation; either version
7 *		2 of the License, or (at your option) any later version.
8 *
9 * Authors:	Richard Alpe <richard.alpe@ericsson.com>
10 */
11
12#include <stdio.h>
13#include <errno.h>
14
15#include <linux/tipc_netlink.h>
16#include <linux/tipc.h>
17#include <linux/genetlink.h>
18#include <libmnl/libmnl.h>
19
20#include "cmdl.h"
21#include "msg.h"
22#include "nametable.h"
23
24#define PORTID_STR_LEN 45 /* Four u32 and five delimiter chars */
25
26static int nametable_show_cb(const struct nlmsghdr *nlh, void *data)
27{
28	int *iteration = data;
29	char port_id[PORTID_STR_LEN];
30	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
31	struct nlattr *info[TIPC_NLA_MAX + 1] = {};
32	struct nlattr *attrs[TIPC_NLA_NAME_TABLE_MAX + 1] = {};
33	struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1] = {};
34	const char *scope[] = { "", "zone", "cluster", "node" };
35
36	mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
37	if (!info[TIPC_NLA_NAME_TABLE])
38		return MNL_CB_ERROR;
39
40	mnl_attr_parse_nested(info[TIPC_NLA_NAME_TABLE], parse_attrs, attrs);
41	if (!attrs[TIPC_NLA_NAME_TABLE_PUBL])
42		return MNL_CB_ERROR;
43
44	mnl_attr_parse_nested(attrs[TIPC_NLA_NAME_TABLE_PUBL], parse_attrs, publ);
45	if (!publ[TIPC_NLA_NAME_TABLE_PUBL])
46		return MNL_CB_ERROR;
47
48	if (!*iteration)
49		printf("%-10s %-10s %-10s %-26s %-10s\n",
50		       "Type", "Lower", "Upper", "Port Identity",
51		       "Publication Scope");
52	(*iteration)++;
53
54	snprintf(port_id, sizeof(port_id), "<%u.%u.%u:%u>",
55		 tipc_zone(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])),
56		 tipc_cluster(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])),
57		 tipc_node(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])),
58		 mnl_attr_get_u32(publ[TIPC_NLA_PUBL_REF]));
59
60	printf("%-10u %-10u %-10u %-26s %-12u",
61	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_TYPE]),
62	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_LOWER]),
63	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_UPPER]),
64	       port_id,
65	       mnl_attr_get_u32(publ[TIPC_NLA_PUBL_KEY]));
66
67	printf("%s\n", scope[mnl_attr_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);
68
69	return MNL_CB_OK;
70}
71
72static int cmd_nametable_show(struct nlmsghdr *nlh, const struct cmd *cmd,
73			      struct cmdl *cmdl, void *data)
74{
75	int iteration = 0;
76	char buf[MNL_SOCKET_BUFFER_SIZE];
77
78	if (help_flag) {
79		fprintf(stderr, "Usage: %s nametable show\n", cmdl->argv[0]);
80		return -EINVAL;
81	}
82
83	if (!(nlh = msg_init(buf, TIPC_NL_NAME_TABLE_GET))) {
84		fprintf(stderr, "error, message initialisation failed\n");
85		return -1;
86	}
87
88	return msg_dumpit(nlh, nametable_show_cb, &iteration);
89}
90
91void cmd_nametable_help(struct cmdl *cmdl)
92{
93	fprintf(stderr,
94		"Usage: %s nametable COMMAND\n\n"
95		"COMMANDS\n"
96		" show                  - Show nametable\n",
97		cmdl->argv[0]);
98}
99
100int cmd_nametable(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
101		  void *data)
102{
103	const struct cmd cmds[] = {
104		{ "show",	cmd_nametable_show,	NULL },
105		{ NULL }
106	};
107
108	return run_cmd(nlh, cmd, cmds, cmdl, NULL);
109}
110