Home | History | Annotate | Download | only in tipc
      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 (at) 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 
     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 
     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 
     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 
    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 
    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 
    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