1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * node.c TIPC node functionality.
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Authors: Richard Alpe <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker */
11*de1e4e89SAndroid Build Coastguard Worker
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <errno.h>
16*de1e4e89SAndroid Build Coastguard Worker
17*de1e4e89SAndroid Build Coastguard Worker #include <linux/tipc_netlink.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <linux/tipc.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <linux/genetlink.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <libmnl/libmnl.h>
21*de1e4e89SAndroid Build Coastguard Worker
22*de1e4e89SAndroid Build Coastguard Worker #include "cmdl.h"
23*de1e4e89SAndroid Build Coastguard Worker #include "msg.h"
24*de1e4e89SAndroid Build Coastguard Worker #include "misc.h"
25*de1e4e89SAndroid Build Coastguard Worker #include "node.h"
26*de1e4e89SAndroid Build Coastguard Worker
node_list_cb(const struct nlmsghdr * nlh,void * data)27*de1e4e89SAndroid Build Coastguard Worker static int node_list_cb(const struct nlmsghdr *nlh, void *data)
28*de1e4e89SAndroid Build Coastguard Worker {
29*de1e4e89SAndroid Build Coastguard Worker uint32_t addr;
30*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
31*de1e4e89SAndroid Build Coastguard Worker struct nlattr *info[TIPC_NLA_MAX + 1] = {};
32*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1] = {};
33*de1e4e89SAndroid Build Coastguard Worker
34*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
35*de1e4e89SAndroid Build Coastguard Worker if (!info[TIPC_NLA_NODE])
36*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
37*de1e4e89SAndroid Build Coastguard Worker
38*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse_nested(info[TIPC_NLA_NODE], parse_attrs, attrs);
39*de1e4e89SAndroid Build Coastguard Worker if (!attrs[TIPC_NLA_NODE_ADDR])
40*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
41*de1e4e89SAndroid Build Coastguard Worker
42*de1e4e89SAndroid Build Coastguard Worker addr = mnl_attr_get_u32(attrs[TIPC_NLA_NODE_ADDR]);
43*de1e4e89SAndroid Build Coastguard Worker printf("<%u.%u.%u>: ",
44*de1e4e89SAndroid Build Coastguard Worker tipc_zone(addr),
45*de1e4e89SAndroid Build Coastguard Worker tipc_cluster(addr),
46*de1e4e89SAndroid Build Coastguard Worker tipc_node(addr));
47*de1e4e89SAndroid Build Coastguard Worker
48*de1e4e89SAndroid Build Coastguard Worker if (attrs[TIPC_NLA_NODE_UP])
49*de1e4e89SAndroid Build Coastguard Worker printf("up\n");
50*de1e4e89SAndroid Build Coastguard Worker else
51*de1e4e89SAndroid Build Coastguard Worker printf("down\n");
52*de1e4e89SAndroid Build Coastguard Worker
53*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
54*de1e4e89SAndroid Build Coastguard Worker }
55*de1e4e89SAndroid Build Coastguard Worker
cmd_node_list(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)56*de1e4e89SAndroid Build Coastguard Worker static int cmd_node_list(struct nlmsghdr *nlh, const struct cmd *cmd,
57*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
58*de1e4e89SAndroid Build Coastguard Worker {
59*de1e4e89SAndroid Build Coastguard Worker char buf[MNL_SOCKET_BUFFER_SIZE];
60*de1e4e89SAndroid Build Coastguard Worker
61*de1e4e89SAndroid Build Coastguard Worker if (help_flag) {
62*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Usage: %s node list\n", cmdl->argv[0]);
63*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
64*de1e4e89SAndroid Build Coastguard Worker }
65*de1e4e89SAndroid Build Coastguard Worker
66*de1e4e89SAndroid Build Coastguard Worker if (!(nlh = msg_init(buf, TIPC_NL_NODE_GET))) {
67*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "error, message initialisation failed\n");
68*de1e4e89SAndroid Build Coastguard Worker return -1;
69*de1e4e89SAndroid Build Coastguard Worker }
70*de1e4e89SAndroid Build Coastguard Worker
71*de1e4e89SAndroid Build Coastguard Worker return msg_dumpit(nlh, node_list_cb, NULL);
72*de1e4e89SAndroid Build Coastguard Worker }
73*de1e4e89SAndroid Build Coastguard Worker
cmd_node_set_addr(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)74*de1e4e89SAndroid Build Coastguard Worker static int cmd_node_set_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
75*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
76*de1e4e89SAndroid Build Coastguard Worker {
77*de1e4e89SAndroid Build Coastguard Worker char *str;
78*de1e4e89SAndroid Build Coastguard Worker uint32_t addr;
79*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nest;
80*de1e4e89SAndroid Build Coastguard Worker char buf[MNL_SOCKET_BUFFER_SIZE];
81*de1e4e89SAndroid Build Coastguard Worker
82*de1e4e89SAndroid Build Coastguard Worker if (cmdl->argc != cmdl->optind + 1) {
83*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Usage: %s node set address ADDRESS\n",
84*de1e4e89SAndroid Build Coastguard Worker cmdl->argv[0]);
85*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
86*de1e4e89SAndroid Build Coastguard Worker }
87*de1e4e89SAndroid Build Coastguard Worker
88*de1e4e89SAndroid Build Coastguard Worker str = shift_cmdl(cmdl);
89*de1e4e89SAndroid Build Coastguard Worker addr = str2addr(str);
90*de1e4e89SAndroid Build Coastguard Worker if (!addr)
91*de1e4e89SAndroid Build Coastguard Worker return -1;
92*de1e4e89SAndroid Build Coastguard Worker
93*de1e4e89SAndroid Build Coastguard Worker if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) {
94*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "error, message initialisation failed\n");
95*de1e4e89SAndroid Build Coastguard Worker return -1;
96*de1e4e89SAndroid Build Coastguard Worker }
97*de1e4e89SAndroid Build Coastguard Worker
98*de1e4e89SAndroid Build Coastguard Worker nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
99*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, TIPC_NLA_NET_ADDR, addr);
100*de1e4e89SAndroid Build Coastguard Worker mnl_attr_nest_end(nlh, nest);
101*de1e4e89SAndroid Build Coastguard Worker
102*de1e4e89SAndroid Build Coastguard Worker return msg_doit(nlh, NULL, NULL);
103*de1e4e89SAndroid Build Coastguard Worker }
104*de1e4e89SAndroid Build Coastguard Worker
cmd_node_get_addr(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)105*de1e4e89SAndroid Build Coastguard Worker static int cmd_node_get_addr(struct nlmsghdr *nlh, const struct cmd *cmd,
106*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
107*de1e4e89SAndroid Build Coastguard Worker {
108*de1e4e89SAndroid Build Coastguard Worker int sk;
109*de1e4e89SAndroid Build Coastguard Worker socklen_t sz = sizeof(struct sockaddr_tipc);
110*de1e4e89SAndroid Build Coastguard Worker struct sockaddr_tipc addr;
111*de1e4e89SAndroid Build Coastguard Worker
112*de1e4e89SAndroid Build Coastguard Worker sk = socket(AF_TIPC, SOCK_RDM, 0);
113*de1e4e89SAndroid Build Coastguard Worker if (sk < 0) {
114*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "opening TIPC socket: %s\n", strerror(errno));
115*de1e4e89SAndroid Build Coastguard Worker return -1;
116*de1e4e89SAndroid Build Coastguard Worker }
117*de1e4e89SAndroid Build Coastguard Worker
118*de1e4e89SAndroid Build Coastguard Worker if (getsockname(sk, (struct sockaddr *)&addr, &sz) < 0) {
119*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "getting TIPC socket address: %s\n",
120*de1e4e89SAndroid Build Coastguard Worker strerror(errno));
121*de1e4e89SAndroid Build Coastguard Worker close(sk);
122*de1e4e89SAndroid Build Coastguard Worker return -1;
123*de1e4e89SAndroid Build Coastguard Worker }
124*de1e4e89SAndroid Build Coastguard Worker close(sk);
125*de1e4e89SAndroid Build Coastguard Worker
126*de1e4e89SAndroid Build Coastguard Worker printf("<%u.%u.%u>\n",
127*de1e4e89SAndroid Build Coastguard Worker tipc_zone(addr.addr.id.node),
128*de1e4e89SAndroid Build Coastguard Worker tipc_cluster(addr.addr.id.node),
129*de1e4e89SAndroid Build Coastguard Worker tipc_node(addr.addr.id.node));
130*de1e4e89SAndroid Build Coastguard Worker
131*de1e4e89SAndroid Build Coastguard Worker return 0;
132*de1e4e89SAndroid Build Coastguard Worker }
133*de1e4e89SAndroid Build Coastguard Worker
netid_get_cb(const struct nlmsghdr * nlh,void * data)134*de1e4e89SAndroid Build Coastguard Worker static int netid_get_cb(const struct nlmsghdr *nlh, void *data)
135*de1e4e89SAndroid Build Coastguard Worker {
136*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
137*de1e4e89SAndroid Build Coastguard Worker struct nlattr *info[TIPC_NLA_MAX + 1] = {};
138*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
139*de1e4e89SAndroid Build Coastguard Worker
140*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
141*de1e4e89SAndroid Build Coastguard Worker if (!info[TIPC_NLA_NET])
142*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
143*de1e4e89SAndroid Build Coastguard Worker
144*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs);
145*de1e4e89SAndroid Build Coastguard Worker if (!attrs[TIPC_NLA_NET_ID])
146*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
147*de1e4e89SAndroid Build Coastguard Worker
148*de1e4e89SAndroid Build Coastguard Worker printf("%u\n", mnl_attr_get_u32(attrs[TIPC_NLA_NET_ID]));
149*de1e4e89SAndroid Build Coastguard Worker
150*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
151*de1e4e89SAndroid Build Coastguard Worker }
152*de1e4e89SAndroid Build Coastguard Worker
cmd_node_get_netid(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)153*de1e4e89SAndroid Build Coastguard Worker static int cmd_node_get_netid(struct nlmsghdr *nlh, const struct cmd *cmd,
154*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
155*de1e4e89SAndroid Build Coastguard Worker {
156*de1e4e89SAndroid Build Coastguard Worker char buf[MNL_SOCKET_BUFFER_SIZE];
157*de1e4e89SAndroid Build Coastguard Worker
158*de1e4e89SAndroid Build Coastguard Worker if (help_flag) {
159*de1e4e89SAndroid Build Coastguard Worker (cmd->help)(cmdl);
160*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
161*de1e4e89SAndroid Build Coastguard Worker }
162*de1e4e89SAndroid Build Coastguard Worker
163*de1e4e89SAndroid Build Coastguard Worker if (!(nlh = msg_init(buf, TIPC_NL_NET_GET))) {
164*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "error, message initialisation failed\n");
165*de1e4e89SAndroid Build Coastguard Worker return -1;
166*de1e4e89SAndroid Build Coastguard Worker }
167*de1e4e89SAndroid Build Coastguard Worker
168*de1e4e89SAndroid Build Coastguard Worker return msg_dumpit(nlh, netid_get_cb, NULL);
169*de1e4e89SAndroid Build Coastguard Worker }
170*de1e4e89SAndroid Build Coastguard Worker
cmd_node_set_netid(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)171*de1e4e89SAndroid Build Coastguard Worker static int cmd_node_set_netid(struct nlmsghdr *nlh, const struct cmd *cmd,
172*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
173*de1e4e89SAndroid Build Coastguard Worker {
174*de1e4e89SAndroid Build Coastguard Worker int netid;
175*de1e4e89SAndroid Build Coastguard Worker char buf[MNL_SOCKET_BUFFER_SIZE];
176*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nest;
177*de1e4e89SAndroid Build Coastguard Worker
178*de1e4e89SAndroid Build Coastguard Worker if (help_flag) {
179*de1e4e89SAndroid Build Coastguard Worker (cmd->help)(cmdl);
180*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
181*de1e4e89SAndroid Build Coastguard Worker }
182*de1e4e89SAndroid Build Coastguard Worker
183*de1e4e89SAndroid Build Coastguard Worker if (!(nlh = msg_init(buf, TIPC_NL_NET_SET))) {
184*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "error, message initialisation failed\n");
185*de1e4e89SAndroid Build Coastguard Worker return -1;
186*de1e4e89SAndroid Build Coastguard Worker }
187*de1e4e89SAndroid Build Coastguard Worker
188*de1e4e89SAndroid Build Coastguard Worker if (cmdl->argc != cmdl->optind + 1) {
189*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Usage: %s node set netid NETID\n",
190*de1e4e89SAndroid Build Coastguard Worker cmdl->argv[0]);
191*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
192*de1e4e89SAndroid Build Coastguard Worker }
193*de1e4e89SAndroid Build Coastguard Worker netid = atoi(shift_cmdl(cmdl));
194*de1e4e89SAndroid Build Coastguard Worker
195*de1e4e89SAndroid Build Coastguard Worker nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
196*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, TIPC_NLA_NET_ID, netid);
197*de1e4e89SAndroid Build Coastguard Worker mnl_attr_nest_end(nlh, nest);
198*de1e4e89SAndroid Build Coastguard Worker
199*de1e4e89SAndroid Build Coastguard Worker return msg_doit(nlh, NULL, NULL);
200*de1e4e89SAndroid Build Coastguard Worker }
201*de1e4e89SAndroid Build Coastguard Worker
cmd_node_set_help(struct cmdl * cmdl)202*de1e4e89SAndroid Build Coastguard Worker static void cmd_node_set_help(struct cmdl *cmdl)
203*de1e4e89SAndroid Build Coastguard Worker {
204*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
205*de1e4e89SAndroid Build Coastguard Worker "Usage: %s node set PROPERTY\n\n"
206*de1e4e89SAndroid Build Coastguard Worker "PROPERTIES\n"
207*de1e4e89SAndroid Build Coastguard Worker " address ADDRESS - Set local address\n"
208*de1e4e89SAndroid Build Coastguard Worker " netid NETID - Set local netid\n",
209*de1e4e89SAndroid Build Coastguard Worker cmdl->argv[0]);
210*de1e4e89SAndroid Build Coastguard Worker }
211*de1e4e89SAndroid Build Coastguard Worker
cmd_node_set(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)212*de1e4e89SAndroid Build Coastguard Worker static int cmd_node_set(struct nlmsghdr *nlh, const struct cmd *cmd,
213*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
214*de1e4e89SAndroid Build Coastguard Worker {
215*de1e4e89SAndroid Build Coastguard Worker const struct cmd cmds[] = {
216*de1e4e89SAndroid Build Coastguard Worker { "address", cmd_node_set_addr, NULL },
217*de1e4e89SAndroid Build Coastguard Worker { "netid", cmd_node_set_netid, NULL },
218*de1e4e89SAndroid Build Coastguard Worker { NULL }
219*de1e4e89SAndroid Build Coastguard Worker };
220*de1e4e89SAndroid Build Coastguard Worker
221*de1e4e89SAndroid Build Coastguard Worker return run_cmd(nlh, cmd, cmds, cmdl, NULL);
222*de1e4e89SAndroid Build Coastguard Worker }
223*de1e4e89SAndroid Build Coastguard Worker
cmd_node_get_help(struct cmdl * cmdl)224*de1e4e89SAndroid Build Coastguard Worker static void cmd_node_get_help(struct cmdl *cmdl)
225*de1e4e89SAndroid Build Coastguard Worker {
226*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
227*de1e4e89SAndroid Build Coastguard Worker "Usage: %s node get PROPERTY\n\n"
228*de1e4e89SAndroid Build Coastguard Worker "PROPERTIES\n"
229*de1e4e89SAndroid Build Coastguard Worker " address - Get local address\n"
230*de1e4e89SAndroid Build Coastguard Worker " netid - Get local netid\n",
231*de1e4e89SAndroid Build Coastguard Worker cmdl->argv[0]);
232*de1e4e89SAndroid Build Coastguard Worker }
233*de1e4e89SAndroid Build Coastguard Worker
cmd_node_get(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)234*de1e4e89SAndroid Build Coastguard Worker static int cmd_node_get(struct nlmsghdr *nlh, const struct cmd *cmd,
235*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
236*de1e4e89SAndroid Build Coastguard Worker {
237*de1e4e89SAndroid Build Coastguard Worker const struct cmd cmds[] = {
238*de1e4e89SAndroid Build Coastguard Worker { "address", cmd_node_get_addr, NULL },
239*de1e4e89SAndroid Build Coastguard Worker { "netid", cmd_node_get_netid, NULL },
240*de1e4e89SAndroid Build Coastguard Worker { NULL }
241*de1e4e89SAndroid Build Coastguard Worker };
242*de1e4e89SAndroid Build Coastguard Worker
243*de1e4e89SAndroid Build Coastguard Worker return run_cmd(nlh, cmd, cmds, cmdl, NULL);
244*de1e4e89SAndroid Build Coastguard Worker }
245*de1e4e89SAndroid Build Coastguard Worker
cmd_node_help(struct cmdl * cmdl)246*de1e4e89SAndroid Build Coastguard Worker void cmd_node_help(struct cmdl *cmdl)
247*de1e4e89SAndroid Build Coastguard Worker {
248*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
249*de1e4e89SAndroid Build Coastguard Worker "Usage: %s node COMMAND [ARGS] ...\n\n"
250*de1e4e89SAndroid Build Coastguard Worker "COMMANDS\n"
251*de1e4e89SAndroid Build Coastguard Worker " list - List remote nodes\n"
252*de1e4e89SAndroid Build Coastguard Worker " get - Get local node parameters\n"
253*de1e4e89SAndroid Build Coastguard Worker " set - Set local node parameters\n",
254*de1e4e89SAndroid Build Coastguard Worker cmdl->argv[0]);
255*de1e4e89SAndroid Build Coastguard Worker }
256*de1e4e89SAndroid Build Coastguard Worker
cmd_node(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)257*de1e4e89SAndroid Build Coastguard Worker int cmd_node(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
258*de1e4e89SAndroid Build Coastguard Worker void *data)
259*de1e4e89SAndroid Build Coastguard Worker {
260*de1e4e89SAndroid Build Coastguard Worker const struct cmd cmds[] = {
261*de1e4e89SAndroid Build Coastguard Worker { "list", cmd_node_list, NULL },
262*de1e4e89SAndroid Build Coastguard Worker { "get", cmd_node_get, cmd_node_get_help },
263*de1e4e89SAndroid Build Coastguard Worker { "set", cmd_node_set, cmd_node_set_help },
264*de1e4e89SAndroid Build Coastguard Worker { NULL }
265*de1e4e89SAndroid Build Coastguard Worker };
266*de1e4e89SAndroid Build Coastguard Worker
267*de1e4e89SAndroid Build Coastguard Worker return run_cmd(nlh, cmd, cmds, cmdl, NULL);
268*de1e4e89SAndroid Build Coastguard Worker }
269