/* mtr -- a network diagnostic tool Copyright (C) 1997,1998 Matt Kimball This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include #include #include #include #include #include #include #include #include "mtr.h" #include "version.h" #include "report.h" #include "net.h" #include "dns.h" #include "asn.h" #define MAXLOADBAL 5 extern int dns; extern char LocalHostname[]; extern char *Hostname; extern int fstTTL; extern int maxTTL; extern int cpacketsize; extern int bitpattern; extern int tos; extern int MaxPing; extern int af; extern int reportwide; char *get_time_string (void) { time_t now; char *t; now = time (NULL); t = ctime (&now); t [ strlen (t) -1] = 0; // remove the trailing newline return t; } void report_open(void) { printf ("Start: %s\n", get_time_string ()); } static size_t snprint_addr(char *dst, size_t dst_len, ip_t *addr) { if(addrcmp((void *) addr, (void *) &unspec_addr, af)) { struct hostent *host = dns ? addr2host((void *) addr, af) : NULL; if (!host) return snprintf(dst, dst_len, "%s", strlongip(addr)); else if (dns && show_ips) return snprintf(dst, dst_len, "%s (%s)", host->h_name, strlongip(addr)); else return snprintf(dst, dst_len, "%s", host->h_name); } else return snprintf(dst, dst_len, "%s", "???"); } #ifdef IPINFO void print_mpls(struct mplslen *mpls) { int k; for (k=0; k < mpls->labels; k++) printf(" [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]); } #endif void report_close(void) { int i, j, at, max, z, w; struct mplslen *mpls, *mplss; ip_t *addr; ip_t *addr2 = NULL; char name[81]; char buf[1024]; char fmt[16]; int len=0; int len_hosts = 33; if (reportwide) { // get the longest hostname len_hosts = strlen(LocalHostname); max = net_max(); at = net_min(); for (; at < max; at++) { int nlen; addr = net_addr(at); if ((nlen = snprint_addr(name, sizeof(name), addr))) if (len_hosts < nlen) len_hosts = nlen; } } #ifdef IPINFO int len_tmp = len_hosts; if (ipinfo_no >= 0) { ipinfo_no %= iiwidth_len; if (reportwide) { len_hosts++; // space len_tmp += get_iiwidth(); if (!ipinfo_no) len_tmp += 2; // align header: AS } } snprintf( fmt, sizeof(fmt), "HOST: %%-%ds", len_tmp); #else snprintf( fmt, sizeof(fmt), "HOST: %%-%ds", len_hosts); #endif snprintf(buf, sizeof(buf), fmt, LocalHostname); len = reportwide ? strlen(buf) : len_hosts; for( i=0; ilabels && z == 1 && enablempls) print_mpls(mpls); snprint_addr(name, sizeof(name), addr2); printf(" %s%s\n", fmt_ipinfo(addr2), name); if (enablempls) print_mpls(mplss); } else { #else int k; if (mpls->labels && z == 1 && enablempls) { for (k=0; k < mpls->labels; k++) { printf(" | |+-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]); } } if (z == 1) { printf (" | `|-- %s\n", strlongip(addr2)); for (k=0; k < mplss->labels && enablempls; k++) { printf(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]); } } else { printf (" | |-- %s\n", strlongip(addr2)); for (k=0; k < mplss->labels && enablempls; k++) { printf(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]); } } #endif #ifdef IPINFO } #endif } } /* No multipath */ #ifdef IPINFO if (is_printii()) { if (mpls->labels && z == 1 && enablempls) print_mpls(mpls); } else { #else if(mpls->labels && z == 1 && enablempls) { int k; for (k=0; k < mpls->labels; k++) { printf(" | +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]); } } #endif #ifdef IPINFO } #endif } } void txt_open(void) { } void txt_close(void) { report_close(); } void xml_open(void) { } void xml_close(void) { int i, j, at, max; ip_t *addr; char name[81]; printf("\n"); printf("= 0) { printf(" PSIZE=\"%d\"", cpacketsize); } else { printf(" PSIZE=\"rand(%d-%d)\"",MINPACKET, -cpacketsize); } if( bitpattern>=0 ) { printf(" BITPATTERN=\"0x%02X\"", (unsigned char)(bitpattern)); } else { printf(" BITPATTERN=\"rand(0x00-FF)\""); } printf(" TESTS=\"%d\">\n", MaxPing); max = net_max(); at = net_min(); for(; at < max; at++) { addr = net_addr(at); snprint_addr(name, sizeof(name), addr); printf(" \n", at+1, name); for( i=0; i"); strcat(name, data_fields[j].format); strcat(name, "\n"); /* XML doesn't allow "%" in tag names, rename Loss% to just Loss */ const char *title; title = data_fields[j].title; if( strcmp(data_fields[j].title, "Loss%") == 0 ) { title = "Loss"; } /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */ if( index( data_fields[j].format, 'f' ) ) { printf( name, title, data_fields[j].net_xxx(at) /1000.0, title ); } else { printf( name, title, data_fields[j].net_xxx(at), title ); } } printf(" \n"); } printf("\n"); } void csv_open(void) { } void csv_close(time_t now) { int i, j, at, max; ip_t *addr; char name[81]; for( i=0; i