tincctl: add node colors and edge weight to graph dump.
This commit is contained in:
parent
40ed0c07dd
commit
368727c3da
3 changed files with 84 additions and 63 deletions
|
@ -2213,6 +2213,9 @@ Dump a list of all meta connections with ourself.
|
|||
|
||||
@item dump graph | digraph
|
||||
Dump a graph of the VPN in dotty format.
|
||||
Nodes are colored according to their reachability:
|
||||
red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable.
|
||||
Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet.
|
||||
|
||||
@item info @var{node} | @var{subnet} | @var{address}
|
||||
Show information about a particular @var{node}, @var{subnet} or @var{address}.
|
||||
|
|
|
@ -128,6 +128,9 @@ Dump a list of all meta connections with ourself.
|
|||
Dump a graph of the VPN in
|
||||
.Xr dotty 1
|
||||
format.
|
||||
Nodes are colored according to their reachability:
|
||||
red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable.
|
||||
Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet.
|
||||
.It info Ar node | subnet | address
|
||||
Show information about a particular node, subnet or address.
|
||||
If an address is given, any matching subnet will be shown.
|
||||
|
|
141
src/tincctl.c
141
src/tincctl.c
|
@ -964,71 +964,86 @@ static int cmd_dump(int argc, char *argv[]) {
|
|||
if(n < 2)
|
||||
break;
|
||||
|
||||
if(!do_graph) {
|
||||
char node[4096];
|
||||
char from[4096];
|
||||
char to[4096];
|
||||
char subnet[4096];
|
||||
char host[4096];
|
||||
char port[4096];
|
||||
char via[4096];
|
||||
char nexthop[4096];
|
||||
int cipher, digest, maclength, compression, distance, socket, weight;
|
||||
short int pmtu, minmtu, maxmtu;
|
||||
unsigned int options, status;
|
||||
long int last_state_change;
|
||||
char node[4096];
|
||||
char from[4096];
|
||||
char to[4096];
|
||||
char subnet[4096];
|
||||
char host[4096];
|
||||
char port[4096];
|
||||
char via[4096];
|
||||
char nexthop[4096];
|
||||
int cipher, digest, maclength, compression, distance, socket, weight;
|
||||
short int pmtu, minmtu, maxmtu;
|
||||
unsigned int options, status_int;
|
||||
node_status_t status;
|
||||
long int last_state_change;
|
||||
|
||||
switch(req) {
|
||||
case REQ_DUMP_NODES: {
|
||||
int n = sscanf(line, "%*d %*d %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, host, port, &cipher, &digest, &maclength, &compression, &options, &status, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
|
||||
if(n != 16) {
|
||||
fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
|
||||
return 1;
|
||||
}
|
||||
printf("%s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n",
|
||||
node, host, port, cipher, digest, maclength, compression, options, status, nexthop, via, distance, pmtu, minmtu, maxmtu);
|
||||
} break;
|
||||
|
||||
case REQ_DUMP_EDGES: {
|
||||
int n = sscanf(line, "%*d %*d %s %s %s port %s %x %d", from, to, host, port, &options, &weight);
|
||||
if(n != 6) {
|
||||
fprintf(stderr, "Unable to parse edge dump from tincd.\n");
|
||||
return 1;
|
||||
}
|
||||
printf("%s to %s at %s port %s options %x weight %d\n", from, to, host, port, options, weight);
|
||||
} break;
|
||||
|
||||
case REQ_DUMP_SUBNETS: {
|
||||
int n = sscanf(line, "%*d %*d %s %s", subnet, node);
|
||||
if(n != 2) {
|
||||
fprintf(stderr, "Unable to parse subnet dump from tincd.\n");
|
||||
return 1;
|
||||
}
|
||||
printf("%s owner %s\n", strip_weight(subnet), node);
|
||||
} break;
|
||||
|
||||
case REQ_DUMP_CONNECTIONS: {
|
||||
int n = sscanf(line, "%*d %*d %s %s port %s %x %d %x", node, host, port, &options, &socket, &status);
|
||||
if(n != 6) {
|
||||
fprintf(stderr, "Unable to parse connection dump from tincd.\n");
|
||||
return 1;
|
||||
}
|
||||
printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status);
|
||||
} break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unable to parse dump from tincd.\n");
|
||||
switch(req) {
|
||||
case REQ_DUMP_NODES: {
|
||||
int n = sscanf(line, "%*d %*d %s %s port %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", node, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change);
|
||||
if(n != 16) {
|
||||
fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if(req == REQ_DUMP_NODES)
|
||||
printf(" %s [label = \"%s\"];\n", node1, node1);
|
||||
else {
|
||||
if(do_graph == 1 && strcmp(node1, node2) > 0)
|
||||
printf(" %s -- %s;\n", node1, node2);
|
||||
else if(do_graph == 2)
|
||||
printf(" %s -> %s;\n", node1, node2);
|
||||
}
|
||||
}
|
||||
if(do_graph) {
|
||||
memcpy(&status, &status_int, sizeof status);
|
||||
const char *color = "black";
|
||||
if(!strcmp(host, "MYSELF"))
|
||||
color = "green";
|
||||
else if(!status.reachable)
|
||||
color = "red";
|
||||
else if(strcmp(via, node))
|
||||
color = "orange";
|
||||
else if(!status.validkey)
|
||||
color = "black";
|
||||
else if(minmtu > 0)
|
||||
color = "green";
|
||||
printf(" %s [label = \"%s\", color = \"%s\"%s];\n", node, node, color, strcmp(host, "MYSELF") ? "" : ", style = \"filled\"");
|
||||
} else {
|
||||
printf("%s at %s port %s cipher %d digest %d maclength %d compression %d options %x status %04x nexthop %s via %s distance %d pmtu %hd (min %hd max %hd)\n",
|
||||
node, host, port, cipher, digest, maclength, compression, options, status_int, nexthop, via, distance, pmtu, minmtu, maxmtu);
|
||||
}
|
||||
} break;
|
||||
|
||||
case REQ_DUMP_EDGES: {
|
||||
int n = sscanf(line, "%*d %*d %s %s %s port %s %x %d", from, to, host, port, &options, &weight);
|
||||
if(n != 6) {
|
||||
fprintf(stderr, "Unable to parse edge dump from tincd.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(do_graph) {
|
||||
float w = 1 + 65536.0 / weight;
|
||||
if(do_graph == 1 && strcmp(node1, node2) > 0)
|
||||
printf(" %s -- %s [w = %f, weight = %f];\n", node1, node2, w, w);
|
||||
else if(do_graph == 2)
|
||||
printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w);
|
||||
} else {
|
||||
printf("%s to %s at %s port %s options %x weight %d\n", from, to, host, port, options, weight);
|
||||
}
|
||||
} break;
|
||||
|
||||
case REQ_DUMP_SUBNETS: {
|
||||
int n = sscanf(line, "%*d %*d %s %s", subnet, node);
|
||||
if(n != 2) {
|
||||
fprintf(stderr, "Unable to parse subnet dump from tincd.\n");
|
||||
return 1;
|
||||
}
|
||||
printf("%s owner %s\n", strip_weight(subnet), node);
|
||||
} break;
|
||||
|
||||
case REQ_DUMP_CONNECTIONS: {
|
||||
int n = sscanf(line, "%*d %*d %s %s port %s %x %d %x", node, host, port, &options, &socket, &status_int);
|
||||
if(n != 6) {
|
||||
fprintf(stderr, "Unable to parse connection dump from tincd.\n");
|
||||
return 1;
|
||||
}
|
||||
printf("%s at %s port %s options %x socket %d status %x\n", node, host, port, options, socket, status_int);
|
||||
} break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unable to parse dump from tincd.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue