Blame ui/report.c

Packit b802ec
/*
Packit b802ec
    mtr  --  a network diagnostic tool
Packit b802ec
    Copyright (C) 1997,1998  Matt Kimball
Packit b802ec
Packit b802ec
    This program is free software; you can redistribute it and/or modify
Packit b802ec
    it under the terms of the GNU General Public License version 2 as
Packit b802ec
    published by the Free Software Foundation.
Packit b802ec
Packit b802ec
    This program is distributed in the hope that it will be useful,
Packit b802ec
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b802ec
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit b802ec
    GNU General Public License for more details.
Packit b802ec
Packit b802ec
    You should have received a copy of the GNU General Public License
Packit b802ec
    along with this program; if not, write to the Free Software
Packit b802ec
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Packit b802ec
*/
Packit b802ec
Packit b802ec
#include "config.h"
Packit b802ec
Packit b802ec
#include <sys/types.h>
Packit b802ec
#include <stdio.h>
Packit b802ec
#include <netdb.h>
Packit b802ec
#include <netinet/in.h>
Packit b802ec
#include <sys/socket.h>
Packit b802ec
#include <string.h>
Packit b802ec
#include <strings.h>
Packit b802ec
#include <time.h>
Packit b802ec
Packit b802ec
#include "mtr.h"
Packit b802ec
#include "report.h"
Packit b802ec
#include "net.h"
Packit b802ec
#include "dns.h"
Packit b802ec
#include "asn.h"
Packit b802ec
#include "utils.h"
Packit b802ec
Packit b802ec
#define MAXLOADBAL 5
Packit b802ec
#define MAX_FORMAT_STR 81
Packit b802ec
Packit b802ec
Packit b802ec
void report_open(
Packit b802ec
    void)
Packit b802ec
{
Packit b802ec
    const time_t now = time(NULL);
Packit b802ec
    const char *t = iso_time(&now;;
Packit b802ec
Packit b802ec
    printf("Start: %s\n", t);
Packit b802ec
}
Packit b802ec
Packit b802ec
static size_t snprint_addr(
Packit b802ec
    struct mtr_ctl *ctl,
Packit b802ec
    char *dst,
Packit b802ec
    size_t dst_len,
Packit b802ec
    ip_t * addr)
Packit b802ec
{
Packit b802ec
    if (addrcmp((void *) addr, (void *) &ctl->unspec_addr, ctl->af)) {
Packit b802ec
        struct hostent *host =
Packit b802ec
            ctl->dns ? addr2host((void *) addr, ctl->af) : NULL;
Packit b802ec
        if (!host)
Packit b802ec
            return snprintf(dst, dst_len, "%s", strlongip(ctl, addr));
Packit b802ec
        else if (ctl->dns && ctl->show_ips)
Packit b802ec
            return snprintf(dst, dst_len, "%s (%s)", host->h_name,
Packit b802ec
                            strlongip(ctl, addr));
Packit b802ec
        else
Packit b802ec
            return snprintf(dst, dst_len, "%s", host->h_name);
Packit b802ec
    } else
Packit b802ec
        return snprintf(dst, dst_len, "%s", "???");
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
static void print_mpls(
Packit b802ec
    struct mplslen *mpls)
Packit b802ec
{
Packit b802ec
    int k;
Packit b802ec
    for (k = 0; k < mpls->labels; k++)
Packit b802ec
        printf("       [MPLS: Lbl %lu Exp %u S %cu TTL %u]\n",
Packit b802ec
               mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
Packit b802ec
}
Packit b802ec
#endif
Packit b802ec
Packit b802ec
void report_close(
Packit b802ec
    struct mtr_ctl *ctl)
Packit b802ec
{
Packit b802ec
    int i, j, at, max, z, w;
Packit b802ec
    struct mplslen *mpls, *mplss;
Packit b802ec
    ip_t *addr;
Packit b802ec
    ip_t *addr2 = NULL;
Packit b802ec
    char name[MAX_FORMAT_STR];
Packit b802ec
    char buf[1024];
Packit b802ec
    char fmt[16];
Packit b802ec
    size_t len = 0;
Packit b802ec
    size_t len_hosts = 33;
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
    int len_tmp;
Packit b802ec
    const size_t iiwidth_len = get_iiwidth_len();
Packit b802ec
#endif
Packit b802ec
Packit b802ec
    if (ctl->reportwide) {
Packit b802ec
        /* get the longest hostname */
Packit b802ec
        len_hosts = strlen(ctl->LocalHostname);
Packit b802ec
        max = net_max(ctl);
Packit b802ec
        at = net_min(ctl);
Packit b802ec
        for (; at < max; at++) {
Packit b802ec
            size_t nlen;
Packit b802ec
            addr = net_addr(at);
Packit b802ec
            if ((nlen = snprint_addr(ctl, name, sizeof(name), addr)))
Packit b802ec
                if (len_hosts < nlen)
Packit b802ec
                    len_hosts = nlen;
Packit b802ec
        }
Packit b802ec
    }
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
    len_tmp = len_hosts;
Packit b802ec
    if (ctl->ipinfo_no >= 0 && iiwidth_len) {
Packit b802ec
        ctl->ipinfo_no %= iiwidth_len;
Packit b802ec
        if (ctl->reportwide) {
Packit b802ec
            len_hosts++;        /* space */
Packit b802ec
            len_tmp += get_iiwidth(ctl->ipinfo_no);
Packit b802ec
            if (!ctl->ipinfo_no)
Packit b802ec
                len_tmp += 2;   /* align header: AS */
Packit b802ec
        }
Packit b802ec
    }
Packit b802ec
    snprintf(fmt, sizeof(fmt), "HOST: %%-%ds", len_tmp);
Packit b802ec
#else
Packit b802ec
    snprintf(fmt, sizeof(fmt), "HOST: %%-%zus", len_hosts);
Packit b802ec
#endif
Packit b802ec
    snprintf(buf, sizeof(buf), fmt, ctl->LocalHostname);
Packit b802ec
    len = ctl->reportwide ? strlen(buf) : len_hosts;
Packit b802ec
    for (i = 0; i < MAXFLD; i++) {
Packit b802ec
        j = ctl->fld_index[ctl->fld_active[i]];
Packit b802ec
        if (j < 0)
Packit b802ec
            continue;
Packit b802ec
Packit b802ec
        snprintf(fmt, sizeof(fmt), "%%%ds", data_fields[j].length);
Packit b802ec
        snprintf(buf + len, sizeof(buf), fmt, data_fields[j].title);
Packit b802ec
        len += data_fields[j].length;
Packit b802ec
    }
Packit b802ec
    printf("%s\n", buf);
Packit b802ec
Packit b802ec
    max = net_max(ctl);
Packit b802ec
    at = net_min(ctl);
Packit b802ec
    for (; at < max; at++) {
Packit b802ec
        addr = net_addr(at);
Packit b802ec
        mpls = net_mpls(at);
Packit b802ec
        snprint_addr(ctl, name, sizeof(name), addr);
Packit b802ec
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
        if (is_printii(ctl)) {
Packit b802ec
            snprintf(fmt, sizeof(fmt), " %%2d. %%s%%-%zus", len_hosts);
Packit b802ec
            snprintf(buf, sizeof(buf), fmt, at + 1, fmt_ipinfo(ctl, addr),
Packit b802ec
                     name);
Packit b802ec
        } else {
Packit b802ec
#endif
Packit b802ec
            snprintf(fmt, sizeof(fmt), " %%2d.|-- %%-%zus", len_hosts);
Packit b802ec
            snprintf(buf, sizeof(buf), fmt, at + 1, name);
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
        }
Packit b802ec
#endif
Packit b802ec
        len = ctl->reportwide ? strlen(buf) : len_hosts;
Packit b802ec
        for (i = 0; i < MAXFLD; i++) {
Packit b802ec
            j = ctl->fld_index[ctl->fld_active[i]];
Packit b802ec
            if (j < 0)
Packit b802ec
                continue;
Packit b802ec
Packit b802ec
            /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
Packit b802ec
            if (strchr(data_fields[j].format, 'f')) {
Packit b802ec
                snprintf(buf + len, sizeof(buf), data_fields[j].format,
Packit b802ec
                         data_fields[j].net_xxx(at) / 1000.0);
Packit b802ec
            } else {
Packit b802ec
                snprintf(buf + len, sizeof(buf), data_fields[j].format,
Packit b802ec
                         data_fields[j].net_xxx(at));
Packit b802ec
            }
Packit b802ec
            len += data_fields[j].length;
Packit b802ec
        }
Packit b802ec
        printf("%s\n", buf);
Packit b802ec
Packit b802ec
        /* This feature shows 'loadbalances' on routes */
Packit b802ec
Packit b802ec
        /* z is starting at 1 because addrs[0] is the same that addr */
Packit b802ec
        for (z = 1; z < MAXPATH; z++) {
Packit b802ec
            int found = 0;
Packit b802ec
            addr2 = net_addrs(at, z);
Packit b802ec
            mplss = net_mplss(at, z);
Packit b802ec
            if ((addrcmp
Packit b802ec
                 ((void *) &ctl->unspec_addr, (void *) addr2,
Packit b802ec
                  ctl->af)) == 0)
Packit b802ec
                break;
Packit b802ec
            for (w = 0; w < z; w++)
Packit b802ec
                /* Ok... checking if there are ips repeated on same hop */
Packit b802ec
                if ((addrcmp
Packit b802ec
                     ((void *) addr2, (void *) net_addrs(at, w),
Packit b802ec
                      ctl->af)) == 0) {
Packit b802ec
                    found = 1;
Packit b802ec
                    break;
Packit b802ec
                }
Packit b802ec
Packit b802ec
            if (!found) {
Packit b802ec
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
                if (is_printii(ctl)) {
Packit b802ec
                    if (mpls->labels && z == 1 && ctl->enablempls)
Packit b802ec
                        print_mpls(mpls);
Packit b802ec
                    snprint_addr(ctl, name, sizeof(name), addr2);
Packit b802ec
                    printf("     %s%s\n", fmt_ipinfo(ctl, addr2), name);
Packit b802ec
                    if (ctl->enablempls)
Packit b802ec
                        print_mpls(mplss);
Packit b802ec
                }
Packit b802ec
#else
Packit b802ec
                int k;
Packit b802ec
                if (mpls->labels && z == 1 && ctl->enablempls) {
Packit b802ec
                    for (k = 0; k < mpls->labels; k++) {
Packit b802ec
                        printf
Packit b802ec
                            ("    |  |+-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n",
Packit b802ec
                             mpls->label[k], mpls->exp[k], mpls->s[k],
Packit b802ec
                             mpls->ttl[k]);
Packit b802ec
                    }
Packit b802ec
                }
Packit b802ec
Packit b802ec
                if (z == 1) {
Packit b802ec
                    printf("    |  `|-- %s\n", strlongip(ctl, addr2));
Packit b802ec
                    for (k = 0; k < mplss->labels && ctl->enablempls; k++) {
Packit b802ec
                        printf
Packit b802ec
                            ("    |   +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n",
Packit b802ec
                             mplss->label[k], mplss->exp[k], mplss->s[k],
Packit b802ec
                             mplss->ttl[k]);
Packit b802ec
                    }
Packit b802ec
                } else {
Packit b802ec
                    printf("    |   |-- %s\n", strlongip(ctl, addr2));
Packit b802ec
                    for (k = 0; k < mplss->labels && ctl->enablempls; k++) {
Packit b802ec
                        printf
Packit b802ec
                            ("    |   +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n",
Packit b802ec
                             mplss->label[k], mplss->exp[k], mplss->s[k],
Packit b802ec
                             mplss->ttl[k]);
Packit b802ec
                    }
Packit b802ec
                }
Packit b802ec
#endif
Packit b802ec
            }
Packit b802ec
        }
Packit b802ec
Packit b802ec
        /* No multipath */
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
        if (is_printii(ctl)) {
Packit b802ec
            if (mpls->labels && z == 1 && ctl->enablempls)
Packit b802ec
                print_mpls(mpls);
Packit b802ec
        }
Packit b802ec
#else
Packit b802ec
        if (mpls->labels && z == 1 && ctl->enablempls) {
Packit b802ec
            int k;
Packit b802ec
            for (k = 0; k < mpls->labels; k++) {
Packit b802ec
                printf("    |   +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n",
Packit b802ec
                       mpls->label[k], mpls->exp[k], mpls->s[k],
Packit b802ec
                       mpls->ttl[k]);
Packit b802ec
            }
Packit b802ec
        }
Packit b802ec
#endif
Packit b802ec
    }
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
void txt_open(
Packit b802ec
    void)
Packit b802ec
{
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
void txt_close(
Packit b802ec
    struct mtr_ctl *ctl)
Packit b802ec
{
Packit b802ec
    report_close(ctl);
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
void json_open(
Packit b802ec
    void)
Packit b802ec
{
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
void json_close(
Packit b802ec
    struct mtr_ctl *ctl)
Packit b802ec
{
Packit b802ec
    int i, j, at, first, max;
Packit b802ec
    ip_t *addr;
Packit b802ec
    char name[MAX_FORMAT_STR];
Packit b802ec
Packit b802ec
    printf("{\n");
Packit b802ec
    printf("  \"report\": {\n");
Packit b802ec
    printf("    \"mtr\": {\n");
Packit b802ec
    printf("      \"src\": \"%s\",\n", ctl->LocalHostname);
Packit b802ec
    printf("      \"dst\": \"%s\",\n", ctl->Hostname);
Packit b802ec
    printf("      \"tos\": \"0x%X\",\n", ctl->tos);
Packit b802ec
    if (ctl->cpacketsize >= 0) {
Packit b802ec
        printf("      \"psize\": \"%d\",\n", ctl->cpacketsize);
Packit b802ec
    } else {
Packit b802ec
        printf("      \"psize\": \"rand(%d-%d)\",\n", MINPACKET,
Packit b802ec
               -ctl->cpacketsize);
Packit b802ec
    }
Packit b802ec
    if (ctl->bitpattern >= 0) {
Packit b802ec
        printf("      \"bitpattern\": \"0x%02X\",\n",
Packit b802ec
               (unsigned char) (ctl->bitpattern));
Packit b802ec
    } else {
Packit b802ec
        printf("      \"bitpattern\": \"rand(0x00-FF)\",\n");
Packit b802ec
    }
Packit b802ec
    printf("      \"tests\": \"%d\"\n", ctl->MaxPing);
Packit b802ec
    printf("    },\n");
Packit b802ec
Packit b802ec
    printf("    \"hubs\": [");
Packit b802ec
Packit b802ec
    max = net_max(ctl);
Packit b802ec
    at = first = net_min(ctl);
Packit b802ec
    for (; at < max; at++) {
Packit b802ec
        addr = net_addr(at);
Packit b802ec
        snprint_addr(ctl, name, sizeof(name), addr);
Packit b802ec
Packit b802ec
        if (at == first) {
Packit b802ec
            printf("{\n");
Packit b802ec
        } else {
Packit b802ec
            printf("    {\n");
Packit b802ec
        }
Packit b802ec
        printf("      \"count\": \"%d\",\n", at + 1);
Packit b802ec
        printf("      \"host\": \"%s\",\n", name);
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
        if(!ctl->ipinfo_no) {
Packit b802ec
          char* fmtinfo = fmt_ipinfo(ctl, addr);
Packit b802ec
          if (fmtinfo != NULL) fmtinfo = trim(fmtinfo, '\0');
Packit b802ec
          printf("      \"ASN\": \"%s\",\n", fmtinfo);
Packit b802ec
        }
Packit b802ec
#endif
Packit b802ec
        for (i = 0; i < MAXFLD; i++) {
Packit b802ec
            const char *format;
Packit b802ec
Packit b802ec
            j = ctl->fld_index[ctl->fld_active[i]];
Packit b802ec
Packit b802ec
            /* Commas */
Packit b802ec
            if (i + 1 == MAXFLD) {
Packit b802ec
                printf("\n");
Packit b802ec
            } else if (j > 0 && i != 0) {
Packit b802ec
                printf(",\n");
Packit b802ec
            }
Packit b802ec
Packit b802ec
            if (j <= 0)
Packit b802ec
                continue;       /* Field nr 0, " " shouldn't be printed in this method. */
Packit b802ec
Packit b802ec
            /* Format value */
Packit b802ec
            format = data_fields[j].format;
Packit b802ec
            if (strchr(format, 'f')) {
Packit b802ec
                format = "%.2f";
Packit b802ec
            } else {
Packit b802ec
                format = "%d";
Packit b802ec
            }
Packit b802ec
Packit b802ec
            /* Format json line */
Packit b802ec
            snprintf(name, sizeof(name), "%s%s", "      \"%s\": ", format);
Packit b802ec
Packit b802ec
            /* Output json line */
Packit b802ec
            if (strchr(data_fields[j].format, 'f')) {
Packit b802ec
                /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
Packit b802ec
                printf(name,
Packit b802ec
                       data_fields[j].title,
Packit b802ec
                       data_fields[j].net_xxx(at) / 1000.0);
Packit b802ec
            } else {
Packit b802ec
                printf(name,
Packit b802ec
                       data_fields[j].title, data_fields[j].net_xxx(at));
Packit b802ec
            }
Packit b802ec
        }
Packit b802ec
        if (at + 1 == max) {
Packit b802ec
            printf("    }]\n");
Packit b802ec
        } else {
Packit b802ec
            printf("    },\n");
Packit b802ec
        }
Packit b802ec
    }
Packit b802ec
    printf("  }\n");
Packit b802ec
    printf("}\n");
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
Packit b802ec
void xml_open(
Packit b802ec
    void)
Packit b802ec
{
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
void xml_close(
Packit b802ec
    struct mtr_ctl *ctl)
Packit b802ec
{
Packit b802ec
    int i, j, at, max;
Packit b802ec
    ip_t *addr;
Packit b802ec
    char name[MAX_FORMAT_STR];
Packit b802ec
Packit b802ec
    printf("\n");
Packit b802ec
    printf("<MTR SRC=\"%s\" DST=\"%s\"", ctl->LocalHostname,
Packit b802ec
           ctl->Hostname);
Packit b802ec
    printf(" TOS=\"0x%X\"", ctl->tos);
Packit b802ec
    if (ctl->cpacketsize >= 0) {
Packit b802ec
        printf(" PSIZE=\"%d\"", ctl->cpacketsize);
Packit b802ec
    } else {
Packit b802ec
        printf(" PSIZE=\"rand(%d-%d)\"", MINPACKET, -ctl->cpacketsize);
Packit b802ec
    }
Packit b802ec
    if (ctl->bitpattern >= 0) {
Packit b802ec
        printf(" BITPATTERN=\"0x%02X\"",
Packit b802ec
               (unsigned char) (ctl->bitpattern));
Packit b802ec
    } else {
Packit b802ec
        printf(" BITPATTERN=\"rand(0x00-FF)\"");
Packit b802ec
    }
Packit b802ec
    printf(" TESTS=\"%d\">\n", ctl->MaxPing);
Packit b802ec
Packit b802ec
    max = net_max(ctl);
Packit b802ec
    at = net_min(ctl);
Packit b802ec
    for (; at < max; at++) {
Packit b802ec
        addr = net_addr(at);
Packit b802ec
        snprint_addr(ctl, name, sizeof(name), addr);
Packit b802ec
Packit b802ec
        printf("    <HUB COUNT=\"%d\" HOST=\"%s\">\n", at + 1, name);
Packit b802ec
        for (i = 0; i < MAXFLD; i++) {
Packit b802ec
            const char *title;
Packit b802ec
Packit b802ec
            j = ctl->fld_index[ctl->fld_active[i]];
Packit b802ec
            if (j <= 0)
Packit b802ec
                continue;       /* Field nr 0, " " shouldn't be printed in this method. */
Packit b802ec
Packit b802ec
            snprintf(name, sizeof(name), "%s%s%s", "        <%s>",
Packit b802ec
                     data_fields[j].format, "</%s>\n");
Packit b802ec
Packit b802ec
            /* XML doesn't allow "%" in tag names, rename Loss% to just Loss */
Packit b802ec
            title = data_fields[j].title;
Packit b802ec
            if (strcmp(data_fields[j].title, "Loss%") == 0) {
Packit b802ec
                title = "Loss";
Packit b802ec
            }
Packit b802ec
Packit b802ec
            /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
Packit b802ec
            if (strchr(data_fields[j].format, 'f')) {
Packit b802ec
                printf(name,
Packit b802ec
                       title, data_fields[j].net_xxx(at) / 1000.0, title);
Packit b802ec
            } else {
Packit b802ec
                printf(name, title, data_fields[j].net_xxx(at), title);
Packit b802ec
            }
Packit b802ec
        }
Packit b802ec
        printf("    </HUB>\n");
Packit b802ec
    }
Packit b802ec
    printf("</MTR>\n");
Packit b802ec
}
Packit b802ec
Packit b802ec
Packit b802ec
void csv_open(
Packit b802ec
    void)
Packit b802ec
{
Packit b802ec
}
Packit b802ec
Packit b802ec
void csv_close(
Packit b802ec
    struct mtr_ctl *ctl,
Packit b802ec
    time_t now)
Packit b802ec
{
Packit b802ec
    int i, j, at, max;
Packit b802ec
    ip_t *addr;
Packit b802ec
    char name[MAX_FORMAT_STR];
Packit b802ec
Packit b802ec
    for (i = 0; i < MAXFLD; i++) {
Packit b802ec
        j = ctl->fld_index[ctl->fld_active[i]];
Packit b802ec
        if (j < 0)
Packit b802ec
            continue;
Packit b802ec
    }
Packit b802ec
Packit b802ec
    max = net_max(ctl);
Packit b802ec
    at = net_min(ctl);
Packit b802ec
    for (; at < max; at++) {
Packit b802ec
        addr = net_addr(at);
Packit b802ec
        snprint_addr(ctl, name, sizeof(name), addr);
Packit b802ec
Packit b802ec
        if (at == net_min(ctl)) {
Packit b802ec
            printf("Mtr_Version,Start_Time,Status,Host,Hop,Ip,");
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
            if (!ctl->ipinfo_no) {
Packit b802ec
                printf("Asn,");
Packit b802ec
            }
Packit b802ec
#endif
Packit b802ec
            for (i = 0; i < MAXFLD; i++) {
Packit b802ec
                j = ctl->fld_index[ctl->fld_active[i]];
Packit b802ec
                if (j < 0)
Packit b802ec
                    continue;
Packit b802ec
                printf("%s,", data_fields[j].title);
Packit b802ec
            }
Packit b802ec
            printf("\n");
Packit b802ec
        }
Packit b802ec
#ifdef HAVE_IPINFO
Packit b802ec
        if (!ctl->ipinfo_no) {
Packit b802ec
            char *fmtinfo = fmt_ipinfo(ctl, addr);
Packit b802ec
            fmtinfo = trim(fmtinfo, '\0');
Packit b802ec
            printf("MTR.%s,%lld,%s,%s,%d,%s,%s", PACKAGE_VERSION,
Packit b802ec
                   (long long) now, "OK", ctl->Hostname, at + 1, name,
Packit b802ec
                   fmtinfo);
Packit b802ec
        } else
Packit b802ec
#endif
Packit b802ec
            printf("MTR.%s,%lld,%s,%s,%d,%s", PACKAGE_VERSION,
Packit b802ec
                   (long long) now, "OK", ctl->Hostname, at + 1, name);
Packit b802ec
Packit b802ec
        for (i = 0; i < MAXFLD; i++) {
Packit b802ec
            j = ctl->fld_index[ctl->fld_active[i]];
Packit b802ec
            if (j < 0)
Packit b802ec
                continue;
Packit b802ec
Packit b802ec
            /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
Packit b802ec
            if (strchr(data_fields[j].format, 'f')) {
Packit b802ec
                printf(",%.2f",
Packit b802ec
                       (double) (data_fields[j].net_xxx(at) / 1000.0));
Packit b802ec
            } else {
Packit b802ec
                printf(",%d", data_fields[j].net_xxx(at));
Packit b802ec
            }
Packit b802ec
        }
Packit b802ec
        printf("\n");
Packit b802ec
    }
Packit b802ec
}