1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * socket.c TIPC socket 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 <errno.h>
14*de1e4e89SAndroid Build Coastguard Worker
15*de1e4e89SAndroid Build Coastguard Worker #include <linux/tipc.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <linux/tipc_netlink.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <linux/genetlink.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <libmnl/libmnl.h>
19*de1e4e89SAndroid Build Coastguard Worker
20*de1e4e89SAndroid Build Coastguard Worker #include "cmdl.h"
21*de1e4e89SAndroid Build Coastguard Worker #include "msg.h"
22*de1e4e89SAndroid Build Coastguard Worker #include "socket.h"
23*de1e4e89SAndroid Build Coastguard Worker
24*de1e4e89SAndroid Build Coastguard Worker #define PORTID_STR_LEN 45 /* Four u32 and five delimiter chars */
25*de1e4e89SAndroid Build Coastguard Worker
publ_list_cb(const struct nlmsghdr * nlh,void * data)26*de1e4e89SAndroid Build Coastguard Worker static int publ_list_cb(const struct nlmsghdr *nlh, void *data)
27*de1e4e89SAndroid Build Coastguard Worker {
28*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
29*de1e4e89SAndroid Build Coastguard Worker struct nlattr *info[TIPC_NLA_MAX + 1] = {};
30*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attrs[TIPC_NLA_SOCK_MAX + 1] = {};
31*de1e4e89SAndroid Build Coastguard Worker
32*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
33*de1e4e89SAndroid Build Coastguard Worker if (!info[TIPC_NLA_PUBL])
34*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
35*de1e4e89SAndroid Build Coastguard Worker
36*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse_nested(info[TIPC_NLA_PUBL], parse_attrs, attrs);
37*de1e4e89SAndroid Build Coastguard Worker
38*de1e4e89SAndroid Build Coastguard Worker printf(" bound to {%u,%u,%u}\n",
39*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(attrs[TIPC_NLA_PUBL_TYPE]),
40*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(attrs[TIPC_NLA_PUBL_LOWER]),
41*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(attrs[TIPC_NLA_PUBL_UPPER]));
42*de1e4e89SAndroid Build Coastguard Worker
43*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
44*de1e4e89SAndroid Build Coastguard Worker }
45*de1e4e89SAndroid Build Coastguard Worker
publ_list(uint32_t sock)46*de1e4e89SAndroid Build Coastguard Worker static int publ_list(uint32_t sock)
47*de1e4e89SAndroid Build Coastguard Worker {
48*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *nlh;
49*de1e4e89SAndroid Build Coastguard Worker char buf[MNL_SOCKET_BUFFER_SIZE];
50*de1e4e89SAndroid Build Coastguard Worker struct nlattr *nest;
51*de1e4e89SAndroid Build Coastguard Worker
52*de1e4e89SAndroid Build Coastguard Worker if (!(nlh = msg_init(buf, TIPC_NL_PUBL_GET))) {
53*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "error, message initialisation failed\n");
54*de1e4e89SAndroid Build Coastguard Worker return -1;
55*de1e4e89SAndroid Build Coastguard Worker }
56*de1e4e89SAndroid Build Coastguard Worker
57*de1e4e89SAndroid Build Coastguard Worker nest = mnl_attr_nest_start(nlh, TIPC_NLA_SOCK);
58*de1e4e89SAndroid Build Coastguard Worker mnl_attr_put_u32(nlh, TIPC_NLA_SOCK_REF, sock);
59*de1e4e89SAndroid Build Coastguard Worker mnl_attr_nest_end(nlh, nest);
60*de1e4e89SAndroid Build Coastguard Worker
61*de1e4e89SAndroid Build Coastguard Worker return msg_dumpit(nlh, publ_list_cb, NULL);
62*de1e4e89SAndroid Build Coastguard Worker }
63*de1e4e89SAndroid Build Coastguard Worker
sock_list_cb(const struct nlmsghdr * nlh,void * data)64*de1e4e89SAndroid Build Coastguard Worker static int sock_list_cb(const struct nlmsghdr *nlh, void *data)
65*de1e4e89SAndroid Build Coastguard Worker {
66*de1e4e89SAndroid Build Coastguard Worker struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
67*de1e4e89SAndroid Build Coastguard Worker struct nlattr *info[TIPC_NLA_MAX + 1] = {};
68*de1e4e89SAndroid Build Coastguard Worker struct nlattr *attrs[TIPC_NLA_SOCK_MAX + 1] = {};
69*de1e4e89SAndroid Build Coastguard Worker
70*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
71*de1e4e89SAndroid Build Coastguard Worker if (!info[TIPC_NLA_SOCK])
72*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
73*de1e4e89SAndroid Build Coastguard Worker
74*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse_nested(info[TIPC_NLA_SOCK], parse_attrs, attrs);
75*de1e4e89SAndroid Build Coastguard Worker if (!attrs[TIPC_NLA_SOCK_REF])
76*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_ERROR;
77*de1e4e89SAndroid Build Coastguard Worker
78*de1e4e89SAndroid Build Coastguard Worker printf("socket %u\n", mnl_attr_get_u32(attrs[TIPC_NLA_SOCK_REF]));
79*de1e4e89SAndroid Build Coastguard Worker
80*de1e4e89SAndroid Build Coastguard Worker if (attrs[TIPC_NLA_SOCK_CON]) {
81*de1e4e89SAndroid Build Coastguard Worker uint32_t node;
82*de1e4e89SAndroid Build Coastguard Worker struct nlattr *con[TIPC_NLA_CON_MAX + 1] = {};
83*de1e4e89SAndroid Build Coastguard Worker
84*de1e4e89SAndroid Build Coastguard Worker mnl_attr_parse_nested(attrs[TIPC_NLA_SOCK_CON], parse_attrs, con);
85*de1e4e89SAndroid Build Coastguard Worker node = mnl_attr_get_u32(con[TIPC_NLA_CON_NODE]);
86*de1e4e89SAndroid Build Coastguard Worker
87*de1e4e89SAndroid Build Coastguard Worker printf(" connected to <%u.%u.%u:%u>", tipc_zone(node),
88*de1e4e89SAndroid Build Coastguard Worker tipc_cluster(node), tipc_node(node),
89*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(con[TIPC_NLA_CON_SOCK]));
90*de1e4e89SAndroid Build Coastguard Worker
91*de1e4e89SAndroid Build Coastguard Worker if (con[TIPC_NLA_CON_FLAG])
92*de1e4e89SAndroid Build Coastguard Worker printf(" via {%u,%u}\n",
93*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(con[TIPC_NLA_CON_TYPE]),
94*de1e4e89SAndroid Build Coastguard Worker mnl_attr_get_u32(con[TIPC_NLA_CON_INST]));
95*de1e4e89SAndroid Build Coastguard Worker else
96*de1e4e89SAndroid Build Coastguard Worker printf("\n");
97*de1e4e89SAndroid Build Coastguard Worker } else if (attrs[TIPC_NLA_SOCK_HAS_PUBL]) {
98*de1e4e89SAndroid Build Coastguard Worker publ_list(mnl_attr_get_u32(attrs[TIPC_NLA_SOCK_REF]));
99*de1e4e89SAndroid Build Coastguard Worker }
100*de1e4e89SAndroid Build Coastguard Worker
101*de1e4e89SAndroid Build Coastguard Worker return MNL_CB_OK;
102*de1e4e89SAndroid Build Coastguard Worker }
103*de1e4e89SAndroid Build Coastguard Worker
cmd_socket_list(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)104*de1e4e89SAndroid Build Coastguard Worker static int cmd_socket_list(struct nlmsghdr *nlh, const struct cmd *cmd,
105*de1e4e89SAndroid Build Coastguard Worker struct cmdl *cmdl, void *data)
106*de1e4e89SAndroid Build Coastguard Worker {
107*de1e4e89SAndroid Build Coastguard Worker char buf[MNL_SOCKET_BUFFER_SIZE];
108*de1e4e89SAndroid Build Coastguard Worker
109*de1e4e89SAndroid Build Coastguard Worker if (help_flag) {
110*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Usage: %s socket list\n", cmdl->argv[0]);
111*de1e4e89SAndroid Build Coastguard Worker return -EINVAL;
112*de1e4e89SAndroid Build Coastguard Worker }
113*de1e4e89SAndroid Build Coastguard Worker
114*de1e4e89SAndroid Build Coastguard Worker if (!(nlh = msg_init(buf, TIPC_NL_SOCK_GET))) {
115*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "error, message initialisation failed\n");
116*de1e4e89SAndroid Build Coastguard Worker return -1;
117*de1e4e89SAndroid Build Coastguard Worker }
118*de1e4e89SAndroid Build Coastguard Worker
119*de1e4e89SAndroid Build Coastguard Worker return msg_dumpit(nlh, sock_list_cb, NULL);
120*de1e4e89SAndroid Build Coastguard Worker }
121*de1e4e89SAndroid Build Coastguard Worker
cmd_socket_help(struct cmdl * cmdl)122*de1e4e89SAndroid Build Coastguard Worker void cmd_socket_help(struct cmdl *cmdl)
123*de1e4e89SAndroid Build Coastguard Worker {
124*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr,
125*de1e4e89SAndroid Build Coastguard Worker "Usage: %s socket COMMAND\n\n"
126*de1e4e89SAndroid Build Coastguard Worker "Commands:\n"
127*de1e4e89SAndroid Build Coastguard Worker " list - List sockets (ports)\n",
128*de1e4e89SAndroid Build Coastguard Worker cmdl->argv[0]);
129*de1e4e89SAndroid Build Coastguard Worker }
130*de1e4e89SAndroid Build Coastguard Worker
cmd_socket(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)131*de1e4e89SAndroid Build Coastguard Worker int cmd_socket(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl,
132*de1e4e89SAndroid Build Coastguard Worker void *data)
133*de1e4e89SAndroid Build Coastguard Worker {
134*de1e4e89SAndroid Build Coastguard Worker const struct cmd cmds[] = {
135*de1e4e89SAndroid Build Coastguard Worker { "list", cmd_socket_list, NULL },
136*de1e4e89SAndroid Build Coastguard Worker { NULL }
137*de1e4e89SAndroid Build Coastguard Worker };
138*de1e4e89SAndroid Build Coastguard Worker
139*de1e4e89SAndroid Build Coastguard Worker return run_cmd(nlh, cmd, cmds, cmdl, NULL);
140*de1e4e89SAndroid Build Coastguard Worker }
141