X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Finfo.c;h=9ac7bbcae36181bd264a1f083a04c8d65e3fb629;hb=72136f8418bc7e8a0a5bf3c11215aa49dc679659;hp=b55257484b5c9095376a4fba6c069074c888a7ef;hpb=3a316823b971396a428f020f401b9fe41252d98d;p=tinc diff --git a/src/info.c b/src/info.c index b5525748..9ac7bbca 100644 --- a/src/info.c +++ b/src/info.c @@ -37,8 +37,11 @@ void logger(int level, int priority, const char *format, ...) { char *strip_weight(char *netstr) { int len = strlen(netstr); - if(len >= 3 && !strcmp(netstr + len - 3, "#10")) + + if(len >= 3 && !strcmp(netstr + len - 3, "#10")) { netstr[len - 3] = 0; + } + return netstr; } @@ -67,14 +70,17 @@ static int info_node(int fd, const char *item) { } status_union; node_status_t status; long int last_state_change; + long int udp_ping_rtt; + uint64_t in_packets, in_bytes, out_packets, out_bytes; while(recvline(fd, line, sizeof(line))) { - int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change); + int n = sscanf(line, "%d %d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld %ld %lu %lu %lu %lu", &code, &req, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_union.raw, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes); - if(n == 2) + if(n == 2) { break; + } - if(n != 19) { + if(n != 24) { fprintf(stderr, "Unable to parse node dump from tincd.\n"); return 1; } @@ -91,8 +97,9 @@ static int info_node(int fd, const char *item) { } while(recvline(fd, line, sizeof(line))) { - if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) + if(sscanf(line, "%d %d %4095s", &code, &req, node) == 2) { break; + } } printf("Node: %s\n", item); @@ -102,88 +109,133 @@ static int info_node(int fd, const char *item) { char timestr[32] = "never"; time_t lsc_time = last_state_change; - if(last_state_change) + if(last_state_change) { strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&lsc_time)); + } status = status_union.bits; - if(status.reachable) + if(status.reachable) { printf("Online since: %s\n", timestr); - else + } else { printf("Last seen: %s\n", timestr); + } printf("Status: "); - if(status.validkey) + + if(status.validkey) { printf(" validkey"); - if(status.visited) + } + + if(status.visited) { printf(" visited"); - if(status.reachable) + } + + if(status.reachable) { printf(" reachable"); - if(status.indirect) + } + + if(status.indirect) { printf(" indirect"); - if(status.sptps) + } + + if(status.sptps) { printf(" sptps"); - if(status.udp_confirmed) + } + + if(status.udp_confirmed) { printf(" udp_confirmed"); + if(udp_ping_rtt != -1) + printf(" (rtt %ld.%03ld)", udp_ping_rtt/1000, udp_ping_rtt%1000); + } + printf("\n"); printf("Options: "); - if(options & OPTION_INDIRECT) + + if(options & OPTION_INDIRECT) { printf(" indirect"); - if(options & OPTION_TCPONLY) + } + + if(options & OPTION_TCPONLY) { printf(" tcponly"); - if(options & OPTION_PMTU_DISCOVERY) + } + + if(options & OPTION_PMTU_DISCOVERY) { printf(" pmtu_discovery"); - if(options & OPTION_CLAMP_MSS) + } + + if(options & OPTION_CLAMP_MSS) { printf(" clamp_mss"); + } + printf("\n"); printf("Protocol: %d.%d\n", PROT_MAJOR, OPTION_VERSION(options)); printf("Reachability: "); - if(!strcmp(host, "MYSELF")) + + if(!strcmp(host, "MYSELF")) { printf("can reach itself\n"); - else if(!status.reachable) + } else if(!status.reachable) { printf("unreachable\n"); - else if(strcmp(via, item)) + } else if(strcmp(via, item)) { printf("indirectly via %s\n", via); - else if(!status.validkey) + } else if(!status.validkey) { printf("unknown\n"); - else if(minmtu > 0) + } else if(minmtu > 0) { printf("directly with UDP\nPMTU: %d\n", pmtu); - else if(!strcmp(nexthop, item)) + } else if(!strcmp(nexthop, item)) { printf("directly with TCP\n"); - else + } else { printf("none, forwarded via %s\n", nexthop); + } + + printf("RX: %lu packets %lu bytes\n", in_packets, in_bytes); + printf("TX: %lu packets %lu bytes\n", out_packets, out_bytes); // List edges printf("Edges: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_EDGES, item); + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, from, to); - if(n == 2) + + if(n == 2) { break; + } + if(n != 4) { fprintf(stderr, "Unable to parse edge dump from tincd.\n%s\n", line); return 1; } - if(!strcmp(from, item)) + + if(!strcmp(from, item)) { printf(" %s", to); + } } + printf("\n"); // List subnets printf("Subnets: "); sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, subnet, from); - if(n == 2) + + if(n == 2) { break; + } + if(n != 4) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; } - if(!strcmp(from, item)) + + if(!strcmp(from, item)) { printf(" %s", strip_weight(subnet)); + } } + printf("\n"); return 0; @@ -208,47 +260,63 @@ static int info_subnet(int fd, const char *item) { int code, req; sendline(fd, "%d %d %s", CONTROL, REQ_DUMP_SUBNETS, item); + while(recvline(fd, line, sizeof(line))) { int n = sscanf(line, "%d %d %4095s %4095s", &code, &req, netstr, owner); - if(n == 2) + + if(n == 2) { break; + } if(n != 4 || !str2net(&subnet, netstr)) { fprintf(stderr, "Unable to parse subnet dump from tincd.\n"); return 1; } - if(find.type != subnet.type) + if(find.type != subnet.type) { continue; + } if(weight) { - if(find.weight != subnet.weight) + if(find.weight != subnet.weight) { continue; + } } if(find.type == SUBNET_IPV4) { if(address) { - if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) + if(maskcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, subnet.net.ipv4.prefixlength)) { continue; + } } else { - if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) + if(find.net.ipv4.prefixlength != subnet.net.ipv4.prefixlength) { continue; - if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof(subnet.net.ipv4))) + } + + if(memcmp(&find.net.ipv4.address, &subnet.net.ipv4.address, sizeof(subnet.net.ipv4))) { continue; + } } } else if(find.type == SUBNET_IPV6) { if(address) { - if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) + if(maskcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, subnet.net.ipv6.prefixlength)) { continue; + } } else { - if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) + if(find.net.ipv6.prefixlength != subnet.net.ipv6.prefixlength) { continue; - if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof(subnet.net.ipv6))) + } + + if(memcmp(&find.net.ipv6.address, &subnet.net.ipv6.address, sizeof(subnet.net.ipv6))) { continue; + } } - } if(find.type == SUBNET_MAC) { - if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof(subnet.net.mac))) + } + + if(find.type == SUBNET_MAC) { + if(memcmp(&find.net.mac.address, &subnet.net.mac.address, sizeof(subnet.net.mac))) { continue; + } } found = true; @@ -257,10 +325,12 @@ static int info_subnet(int fd, const char *item) { } if(!found) { - if(address) + if(address) { fprintf(stderr, "Unknown address %s.\n", item); - else + } else { fprintf(stderr, "Unknown subnet %s.\n", item); + } + return 1; } @@ -268,10 +338,13 @@ static int info_subnet(int fd, const char *item) { } int info(int fd, const char *item) { - if(check_id(item)) + if(check_id(item)) { return info_node(fd, item); - if(strchr(item, '.') || strchr(item, ':')) + } + + if(strchr(item, '.') || strchr(item, ':')) { return info_subnet(fd, item); + } fprintf(stderr, "Argument is not a node name, subnet or address.\n"); return 1;