tincctl: add node colors and edge weight to graph dump.

This commit is contained in:
Guus Sliepen 2012-10-14 16:07:35 +02:00
parent 40ed0c07dd
commit 368727c3da
3 changed files with 84 additions and 63 deletions

View file

@ -2213,6 +2213,9 @@ Dump a list of all meta connections with ourself.
@item dump graph | digraph @item dump graph | digraph
Dump a graph of the VPN in dotty format. 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} @item info @var{node} | @var{subnet} | @var{address}
Show information about a particular @var{node}, @var{subnet} or @var{address}. Show information about a particular @var{node}, @var{subnet} or @var{address}.

View file

@ -128,6 +128,9 @@ Dump a list of all meta connections with ourself.
Dump a graph of the VPN in Dump a graph of the VPN in
.Xr dotty 1 .Xr dotty 1
format. 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 .It info Ar node | subnet | address
Show information about a particular node, subnet or address. Show information about a particular node, subnet or address.
If an address is given, any matching subnet will be shown. If an address is given, any matching subnet will be shown.

View file

@ -964,71 +964,86 @@ static int cmd_dump(int argc, char *argv[]) {
if(n < 2) if(n < 2)
break; break;
if(!do_graph) { char node[4096];
char node[4096]; char from[4096];
char from[4096]; char to[4096];
char to[4096]; char subnet[4096];
char subnet[4096]; char host[4096];
char host[4096]; char port[4096];
char port[4096]; char via[4096];
char via[4096]; char nexthop[4096];
char nexthop[4096]; int cipher, digest, maclength, compression, distance, socket, weight;
int cipher, digest, maclength, compression, distance, socket, weight; short int pmtu, minmtu, maxmtu;
short int pmtu, minmtu, maxmtu; unsigned int options, status_int;
unsigned int options, status; node_status_t status;
long int last_state_change; long int last_state_change;
switch(req) { switch(req) {
case REQ_DUMP_NODES: { 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); 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) { if(n != 16) {
fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line); 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");
return 1; return 1;
} }
} else { if(do_graph) {
if(req == REQ_DUMP_NODES) memcpy(&status, &status_int, sizeof status);
printf(" %s [label = \"%s\"];\n", node1, node1); const char *color = "black";
else { if(!strcmp(host, "MYSELF"))
if(do_graph == 1 && strcmp(node1, node2) > 0) color = "green";
printf(" %s -- %s;\n", node1, node2); else if(!status.reachable)
else if(do_graph == 2) color = "red";
printf(" %s -> %s;\n", node1, node2); 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;
} }
} }