X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Ftincctl.c;h=5916d7b5cb1f9167cd01590bbc0f9fa15d0a0990;hb=1f312137d5ab12a2d996d5f7972f169aeb852040;hp=00d8eb903d27fcddca01741105dea06deb769729;hpb=d74b81b61e87c66d364a8590a48d87773ad2652c;p=tinc diff --git a/src/tincctl.c b/src/tincctl.c index 00d8eb90..5916d7b5 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -138,7 +138,7 @@ static void usage(bool status) { " edges - all known connections in the VPN\n" " subnets - all known subnets in the VPN\n" " connections - all meta connections with ourself\n" - " graph - graph of the VPN in dotty format\n" + " [di]graph - graph of the VPN in dotty format\n" " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n" " purge Purge unreachable nodes\n" " debug N Set debug level\n" @@ -822,7 +822,7 @@ static int cmd_dump(int argc, char *argv[]) { if(!connect_tincd(true)) return 1; - bool do_graph = false; + int do_graph = 0; if(!strcasecmp(argv[1], "nodes")) sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); @@ -835,19 +835,25 @@ static int cmd_dump(int argc, char *argv[]) { else if(!strcasecmp(argv[1], "graph")) { sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); - do_graph = true; + do_graph = 1; + } else if(!strcasecmp(argv[1], "digraph")) { + sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES); + sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES); + do_graph = 2; } else { fprintf(stderr, "Unknown dump type '%s'.\n", argv[1]); usage(true); return 1; } - if(do_graph) + if(do_graph == 1) + printf("graph {\n"); + else if(do_graph == 2) printf("digraph {\n"); while(recvline(fd, line, sizeof line)) { char node1[4096], node2[4096]; - int n = sscanf(line, "%d %d %s to %s", &code, &req, node1, node2); + int n = sscanf(line, "%d %d %s %s", &code, &req, node1, node2); if(n == 2) { if(do_graph && req == REQ_DUMP_NODES) continue; @@ -860,13 +866,71 @@ static int cmd_dump(int argc, char *argv[]) { if(n < 2) break; - if(!do_graph) - printf("%s\n", line + 5); - else { + 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; + + 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"); + return 1; + } + } else { if(req == REQ_DUMP_NODES) printf(" %s [label = \"%s\"];\n", node1, node1); - else - printf(" %s -> %s;\n", node1, node2); + 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); + } } }