mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-05 07:43:30 +00:00

We make it easier for users to correlate between 128-bit node identities and 32-bit node hash number by extending the 'node list' command to also show the hash number. We also improve the 'nametable show' command to show the node identity instead of the node hash number. Since the former potentially is much longer than the latter, we make room for it by eliminating the (to the user) irrelevant publication key. We also reorder some of the columns so that the node id comes last, since this looks nicer and is more logical. Signed-off-by: David Ahern <dsahern@gmail.com>
132 lines
2.5 KiB
C
132 lines
2.5 KiB
C
/*
|
|
* misc.c Miscellaneous TIPC helper functions.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version
|
|
* 2 of the License, or (at your option) any later version.
|
|
*
|
|
* Authors: Richard Alpe <richard.alpe@ericsson.com>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <linux/tipc.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include "misc.h"
|
|
|
|
#define IN_RANGE(val, low, high) ((val) <= (high) && (val) >= (low))
|
|
|
|
uint32_t str2addr(char *str)
|
|
{
|
|
unsigned int z, c, n;
|
|
char dummy;
|
|
|
|
if (sscanf(str, "%u.%u.%u%c", &z, &c, &n, &dummy) != 3) {
|
|
fprintf(stderr, "invalid network address, syntax: Z.C.N\n");
|
|
return 0;
|
|
}
|
|
|
|
if (IN_RANGE(z, 0, 255) && IN_RANGE(c, 0, 4095) && IN_RANGE(n, 0, 4095))
|
|
return tipc_addr(z, c, n);
|
|
|
|
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;
|
|
}
|
|
|
|
void hash2nodestr(uint32_t hash, char *str)
|
|
{
|
|
struct tipc_sioc_nodeid_req nr = {};
|
|
int sd;
|
|
|
|
sd = socket(AF_TIPC, SOCK_RDM, 0);
|
|
if (sd < 0) {
|
|
fprintf(stderr, "opening TIPC socket: %s\n", strerror(errno));
|
|
return;
|
|
}
|
|
nr.peer = hash;
|
|
if (!ioctl(sd, SIOCGETNODEID, &nr))
|
|
nodeid2str((uint8_t *)nr.node_id, str);
|
|
close(sd);
|
|
}
|