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