#include <stdio.h>
#include <stdint.h>
#include <linux/tipc.h>
-
+#include <string.h>
#include "misc.h"
#define IN_RANGE(val, low, high) ((val) <= (high) && (val) >= (low))
fprintf(stderr, "invalid network address \"%s\"\n", str);
return 0;
}
+
+static int is_hex(char *arr, int last)
+{
+ int i;
+
+ while (!arr[last])
+ last--;
+
+ for (i = 0; i <= last; i++) {
+ if (!IN_RANGE(arr[i], '0', '9') &&
+ !IN_RANGE(arr[i], 'a', 'f') &&
+ !IN_RANGE(arr[i], 'A', 'F'))
+ return 0;
+ }
+ return 1;
+}
+
+static int is_name(char *arr, int last)
+{
+ int i;
+ char c;
+
+ while (!arr[last])
+ last--;
+
+ if (last > 15)
+ return 0;
+
+ for (i = 0; i <= last; i++) {
+ c = arr[i];
+ if (!IN_RANGE(c, '0', '9') && !IN_RANGE(c, 'a', 'z') &&
+ !IN_RANGE(c, 'A', 'Z') && c != '-' && c != '_' &&
+ c != '.' && c != ':' && c != '@')
+ return 0;
+ }
+ return 1;
+}
+
+int str2nodeid(char *str, uint8_t *id)
+{
+ int len = strlen(str);
+ int i;
+
+ if (len > 32)
+ return -1;
+
+ if (is_name(str, len - 1)) {
+ memcpy(id, str, len);
+ return 0;
+ }
+ if (!is_hex(str, len - 1))
+ return -1;
+
+ str[len] = '0';
+ for (i = 0; i < 16; i++) {
+ if (sscanf(&str[2 * i], "%2hhx", &id[i]) != 1)
+ break;
+ }
+ return 0;
+}
+
+void nodeid2str(uint8_t *id, char *str)
+{
+ int i;
+
+ if (is_name((char *)id, 15)) {
+ memcpy(str, id, 16);
+ return;
+ }
+
+ for (i = 0; i < 16; i++)
+ sprintf(&str[2 * i], "%02x", id[i]);
+
+ for (i = 31; str[i] == '0'; i--)
+ str[i] = 0;
+}
return 0;
}
+static int cmd_node_set_nodeid(struct nlmsghdr *nlh, const struct cmd *cmd,
+ struct cmdl *cmdl, void *data)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ uint8_t id[16] = {0,};
+ uint64_t *w0 = (uint64_t *) &id[0];
+ uint64_t *w1 = (uint64_t *) &id[8];
+ struct nlattr *nest;
+ char *str;
+
+ if (cmdl->argc != cmdl->optind + 1) {
+ fprintf(stderr, "Usage: %s node set nodeid NODE_ID\n",
+ cmdl->argv[0]);
+ return -EINVAL;
+ }
+
+ str = shift_cmdl(cmdl);
+ if (str2nodeid(str, id)) {
+ fprintf(stderr, "Invalid node identity\n");
+ return -EINVAL;
+ }
+
+ nlh = msg_init(buf, TIPC_NL_NET_SET);
+ if (!nlh) {
+ fprintf(stderr, "error, message initialisation failed\n");
+ return -1;
+ }
+ nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET);
+ mnl_attr_put_u64(nlh, TIPC_NLA_NET_NODEID, *w0);
+ mnl_attr_put_u64(nlh, TIPC_NLA_NET_NODEID_W1, *w1);
+ mnl_attr_nest_end(nlh, nest);
+ return msg_doit(nlh, NULL, NULL);
+}
+
+static int nodeid_get_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+ struct nlattr *info[TIPC_NLA_MAX + 1] = {};
+ struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {};
+ char str[33] = {0,};
+ uint8_t id[16] = {0,};
+ uint64_t *w0 = (uint64_t *) &id[0];
+ uint64_t *w1 = (uint64_t *) &id[8];
+ int i;
+
+ mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info);
+ if (!info[TIPC_NLA_NET])
+ return MNL_CB_ERROR;
+
+ mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs);
+ if (!attrs[TIPC_NLA_NET_ID])
+ return MNL_CB_ERROR;
+
+ *w0 = mnl_attr_get_u64(attrs[TIPC_NLA_NET_NODEID]);
+ *w1 = mnl_attr_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]);
+ nodeid2str(id, str);
+ printf("Node Identity Hash\n");
+ printf("%s", str);
+ for (i = strlen(str); i <= 33; i++)
+ printf(" ");
+ cmd_node_get_addr(NULL, NULL, NULL, NULL);
+ return MNL_CB_OK;
+}
+
+static int cmd_node_get_nodeid(struct nlmsghdr *nlh, const struct cmd *cmd,
+ struct cmdl *cmdl, void *data)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+
+ if (help_flag) {
+ (cmd->help)(cmdl);
+ return -EINVAL;
+ }
+
+ nlh = msg_init(buf, TIPC_NL_NET_GET);
+ if (!nlh) {
+ fprintf(stderr, "error, message initialisation failed\n");
+ return -1;
+ }
+
+ return msg_dumpit(nlh, nodeid_get_cb, NULL);
+}
+
+
static int netid_get_cb(const struct nlmsghdr *nlh, void *data)
{
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
fprintf(stderr,
"Usage: %s node set PROPERTY\n\n"
"PROPERTIES\n"
- " address ADDRESS - Set local address\n"
- " netid NETID - Set local netid\n",
+ " identity NODEID - Set node identity\n"
+ " clusterid CLUSTERID - Set local cluster id\n",
cmdl->argv[0]);
}
struct cmdl *cmdl, void *data)
{
const struct cmd cmds[] = {
- { "address", cmd_node_set_addr, NULL },
+ { "address", cmd_node_set_addr, NULL },
+ { "identity", cmd_node_set_nodeid, NULL },
{ "netid", cmd_node_set_netid, NULL },
+ { "clusterid", cmd_node_set_netid, NULL },
{ NULL }
};
fprintf(stderr,
"Usage: %s node get PROPERTY\n\n"
"PROPERTIES\n"
- " address - Get local address\n"
- " netid - Get local netid\n",
+ " identity - Get node identity\n"
+ " clusterid - Get local clusterid\n",
cmdl->argv[0]);
}
{
const struct cmd cmds[] = {
{ "address", cmd_node_get_addr, NULL },
+ { "identity", cmd_node_get_nodeid, NULL },
{ "netid", cmd_node_get_netid, NULL },
+ { "clusterid", cmd_node_get_netid, NULL },
{ NULL }
};