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