Annotation of embedaddon/mtr/report.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:     mtr  --  a network diagnostic tool
                      3:     Copyright (C) 1997,1998  Matt Kimball
                      4: 
                      5:     This program is free software; you can redistribute it and/or modify
                      6:     it under the terms of the GNU General Public License version 2 as 
                      7:     published by the Free Software Foundation.
                      8: 
                      9:     This program is distributed in the hope that it will be useful,
                     10:     but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     12:     GNU General Public License for more details.
                     13: 
                     14:     You should have received a copy of the GNU General Public License
                     15:     along with this program; if not, write to the Free Software
                     16:     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17: */
                     18: 
1.1.1.2 ! misho      19: #include "config.h"
        !            20: 
1.1       misho      21: #include <sys/types.h>
                     22: #include <stdio.h>
                     23: #include <netdb.h>
                     24: #include <netinet/in.h>
                     25: #include <sys/socket.h>
                     26: #include <string.h>
                     27: #include <strings.h>
                     28: #include <time.h>
                     29: 
                     30: #include "mtr.h"
                     31: #include "version.h"
                     32: #include "report.h"
                     33: #include "net.h"
                     34: #include "dns.h"
                     35: #include "asn.h"
                     36: 
                     37: #define MAXLOADBAL 5
                     38: 
                     39: extern int dns;
                     40: extern char LocalHostname[];
                     41: extern char *Hostname;
                     42: extern int fstTTL;
                     43: extern int maxTTL;
                     44: extern int cpacketsize;
                     45: extern int bitpattern;
                     46: extern int tos;
                     47: extern int MaxPing;
                     48: extern int af;
                     49: extern int reportwide;
                     50: 
                     51: 
                     52: char *get_time_string (void) 
                     53: {
                     54:   time_t now; 
                     55:   char *t;
                     56:   now = time (NULL);
                     57:   t = ctime (&now);
                     58:   t [ strlen (t) -1] = 0; // remove the trailing newline
                     59:   return t;
                     60: }
                     61: 
                     62: void report_open(void)
                     63: {
                     64:   printf ("Start: %s\n", get_time_string ());
                     65: }
                     66: 
                     67: static size_t snprint_addr(char *dst, size_t dst_len, ip_t *addr)
                     68: {
                     69:   if(addrcmp((void *) addr, (void *) &unspec_addr, af)) {
                     70:     struct hostent *host = dns ? addr2host((void *) addr, af) : NULL;
                     71:     if (!host) return snprintf(dst, dst_len, "%s", strlongip(addr));
                     72:     else if (dns && show_ips)
                     73:       return snprintf(dst, dst_len, "%s (%s)", host->h_name, strlongip(addr));
                     74:     else return snprintf(dst, dst_len, "%s", host->h_name);
                     75:   } else return snprintf(dst, dst_len, "%s", "???");
                     76: }
                     77: 
                     78: 
1.1.1.2 ! misho      79: #ifdef IPINFO
1.1       misho      80: void print_mpls(struct mplslen *mpls) {
                     81:   int k;
                     82:   for (k=0; k < mpls->labels; k++)
                     83:     printf("       [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
                     84: }
                     85: #endif
                     86: 
                     87: void report_close(void) 
                     88: {
                     89:   int i, j, at, max, z, w;
                     90:   struct mplslen *mpls, *mplss;
                     91:   ip_t *addr;
                     92:   ip_t *addr2 = NULL;  
                     93:   char name[81];
                     94:   char buf[1024];
                     95:   char fmt[16];
                     96:   int len=0;
                     97:   int len_hosts = 33;
                     98: 
                     99:   if (reportwide)
                    100:   {
                    101:     // get the longest hostname
                    102:     len_hosts = strlen(LocalHostname);
                    103:     max = net_max();
                    104:     at  = net_min();
                    105:     for (; at < max; at++) {
                    106:       int nlen;
                    107:       addr = net_addr(at);
                    108:       if ((nlen = snprint_addr(name, sizeof(name), addr)))
                    109:         if (len_hosts < nlen)
                    110:           len_hosts = nlen;
                    111:     }
                    112:   }
                    113:   
1.1.1.2 ! misho     114: #ifdef IPINFO
1.1       misho     115:   int len_tmp = len_hosts;
                    116:   if (ipinfo_no >= 0) {
                    117:     ipinfo_no %= iiwidth_len;
                    118:     if (reportwide) {
                    119:       len_hosts++;    // space
                    120:       len_tmp   += get_iiwidth();
                    121:       if (!ipinfo_no)
                    122:         len_tmp += 2; // align header: AS
                    123:     }
                    124:   }
                    125:   snprintf( fmt, sizeof(fmt), "HOST: %%-%ds", len_tmp);
                    126: #else
                    127:   snprintf( fmt, sizeof(fmt), "HOST: %%-%ds", len_hosts);
                    128: #endif
                    129:   snprintf(buf, sizeof(buf), fmt, LocalHostname);
                    130:   len = reportwide ? strlen(buf) : len_hosts;
                    131:   for( i=0; i<MAXFLD; i++ ) {
                    132:     j = fld_index[fld_active[i]];
                    133:     if (j < 0) continue;
                    134: 
                    135:     snprintf( fmt, sizeof(fmt), "%%%ds", data_fields[j].length );
                    136:     snprintf( buf + len, sizeof(buf), fmt, data_fields[j].title );
                    137:     len +=  data_fields[j].length;
                    138:   }
                    139:   printf("%s\n",buf);
                    140: 
                    141:   max = net_max();
                    142:   at  = net_min();
                    143:   for(; at < max; at++) {
                    144:     addr = net_addr(at);
                    145:     mpls = net_mpls(at);
                    146:     snprint_addr(name, sizeof(name), addr);
                    147: 
1.1.1.2 ! misho     148: #ifdef IPINFO
1.1       misho     149:     if (is_printii()) {
                    150:       snprintf(fmt, sizeof(fmt), " %%2d. %%s%%-%ds", len_hosts);
                    151:       snprintf(buf, sizeof(buf), fmt, at+1, fmt_ipinfo(addr), name);
                    152:     } else {
                    153: #endif
                    154:     snprintf( fmt, sizeof(fmt), " %%2d.|-- %%-%ds", len_hosts);
                    155:     snprintf(buf, sizeof(buf), fmt, at+1, name);
1.1.1.2 ! misho     156: #ifdef IPINFO
1.1       misho     157:     }
                    158: #endif
                    159:     len = reportwide ? strlen(buf) : len_hosts;  
                    160:     for( i=0; i<MAXFLD; i++ ) {
                    161:       j = fld_index[fld_active [i]];
                    162:       if (j < 0) continue;
                    163: 
                    164:       /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
                    165:       if( index( data_fields[j].format, 'f' ) ) {
                    166:         snprintf( buf + len, sizeof(buf), data_fields[j].format,
                    167:                data_fields[j].net_xxx(at) /1000.0 );
                    168:       } else {
                    169:         snprintf( buf + len, sizeof(buf), data_fields[j].format,
                    170:                data_fields[j].net_xxx(at) );
                    171:       }
                    172:       len +=  data_fields[j].length;
                    173:     }
                    174:     printf("%s\n",buf);
                    175: 
                    176:     /* This feature shows 'loadbalances' on routes */
                    177: 
                    178:     /* z is starting at 1 because addrs[0] is the same that addr */
                    179:     for (z = 1; z < MAXPATH ; z++) {
                    180:       addr2 = net_addrs(at, z);
                    181:       mplss = net_mplss(at, z);
                    182:       int found = 0;
                    183:       if ((addrcmp ((void *) &unspec_addr, (void *) addr2, af)) == 0)
                    184:         break;
                    185:       for (w = 0; w < z; w++)
                    186:         /* Ok... checking if there are ips repeated on same hop */
                    187:         if ((addrcmp ((void *) addr2, (void *) net_addrs (at,w), af)) == 0) {
                    188:            found = 1;
                    189:            break;
                    190:         }   
                    191: 
                    192:       if (!found) {
                    193:   
1.1.1.2 ! misho     194: #ifdef IPINFO
1.1       misho     195:         if (is_printii()) {
                    196:           if (mpls->labels && z == 1 && enablempls)
                    197:             print_mpls(mpls);
                    198:           snprint_addr(name, sizeof(name), addr2);
                    199:           printf("     %s%s\n", fmt_ipinfo(addr2), name);
                    200:           if (enablempls)
                    201:             print_mpls(mplss);
                    202:         } else {
                    203: #else
                    204:         int k;
                    205:         if (mpls->labels && z == 1 && enablempls) {
                    206:           for (k=0; k < mpls->labels; k++) {
                    207:             printf("    |  |+-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
                    208:           }
                    209:         }
                    210: 
                    211:         if (z == 1) {
                    212:           printf ("    |  `|-- %s\n", strlongip(addr2));
                    213:           for (k=0; k < mplss->labels && enablempls; k++) {
                    214:             printf("    |   +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]);
                    215:           }
                    216:         } else {
                    217:           printf ("    |   |-- %s\n", strlongip(addr2));
                    218:           for (k=0; k < mplss->labels && enablempls; k++) {
                    219:             printf("    |   +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mplss->label[k], mplss->exp[k], mplss->s[k], mplss->ttl[k]);
                    220:           }
                    221:         }
                    222: #endif
1.1.1.2 ! misho     223: #ifdef IPINFO
1.1       misho     224:         }
                    225: #endif
                    226:       }
                    227:     }
                    228: 
                    229:     /* No multipath */
1.1.1.2 ! misho     230: #ifdef IPINFO
1.1       misho     231:     if (is_printii()) {
                    232:       if (mpls->labels && z == 1 && enablempls)
                    233:         print_mpls(mpls);
                    234:     } else {
                    235: #else
                    236:     if(mpls->labels && z == 1 && enablempls) {
                    237:       int k;
                    238:       for (k=0; k < mpls->labels; k++) {
                    239:         printf("    |   +-- [MPLS: Lbl %lu Exp %u S %u TTL %u]\n", mpls->label[k], mpls->exp[k], mpls->s[k], mpls->ttl[k]);
                    240:       }
                    241:     }
                    242: #endif
1.1.1.2 ! misho     243: #ifdef IPINFO
1.1       misho     244:     }
                    245: #endif
                    246:   }
                    247: }
                    248: 
                    249: 
                    250: void txt_open(void)
                    251: {
                    252: }
                    253: 
                    254: 
                    255: void txt_close(void)
                    256: { 
                    257:   report_close();
                    258: }
                    259: 
                    260: 
                    261: 
                    262: void xml_open(void)
                    263: {
                    264: }
                    265: 
                    266: 
                    267: void xml_close(void)
                    268: {
                    269:   int i, j, at, max;
                    270:   ip_t *addr;
                    271:   char name[81];
                    272: 
1.1.1.2 ! misho     273:   printf("<?xml version=\"1.0\"?>\n");
        !           274:   printf("<MTR SRC=\"%s\" DST=\"%s\"", LocalHostname, Hostname);
        !           275:   printf(" TOS=\"0x%X\"", tos);
1.1       misho     276:   if(cpacketsize >= 0) {
1.1.1.2 ! misho     277:     printf(" PSIZE=\"%d\"", cpacketsize);
1.1       misho     278:   } else {
1.1.1.2 ! misho     279:     printf(" PSIZE=\"rand(%d-%d)\"",MINPACKET, -cpacketsize);
1.1       misho     280:   }
                    281:   if( bitpattern>=0 ) {
1.1.1.2 ! misho     282:     printf(" BITPATTERN=\"0x%02X\"", (unsigned char)(bitpattern));
1.1       misho     283:   } else {
1.1.1.2 ! misho     284:     printf(" BITPATTERN=\"rand(0x00-FF)\"");
1.1       misho     285:   }
1.1.1.2 ! misho     286:   printf(" TESTS=\"%d\">\n", MaxPing);
1.1       misho     287: 
                    288:   max = net_max();
                    289:   at  = net_min();
                    290:   for(; at < max; at++) {
                    291:     addr = net_addr(at);
                    292:     snprint_addr(name, sizeof(name), addr);
                    293: 
1.1.1.2 ! misho     294:     printf("    <HUB COUNT=\"%d\" HOST=\"%s\">\n", at+1, name);
1.1       misho     295:     for( i=0; i<MAXFLD; i++ ) {
                    296:       j = fld_index[fld_active[i]];
                    297:       if (j < 0) continue;
                    298: 
                    299:       strcpy(name, "        <%s>");
                    300:       strcat(name, data_fields[j].format);
                    301:       strcat(name, "</%s>\n");
1.1.1.2 ! misho     302: 
        !           303:       /* XML doesn't allow "%" in tag names, rename Loss% to just Loss */
        !           304:       const char *title;
        !           305:       title = data_fields[j].title;
        !           306:       if( strcmp(data_fields[j].title, "Loss%") == 0 ) {
        !           307:                title = "Loss";
        !           308:       }
        !           309: 
1.1       misho     310:       /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
                    311:       if( index( data_fields[j].format, 'f' ) ) {
                    312:        printf( name,
1.1.1.2 ! misho     313:                title,
1.1       misho     314:                data_fields[j].net_xxx(at) /1000.0,
1.1.1.2 ! misho     315:                title );
1.1       misho     316:       } else {
                    317:        printf( name,
1.1.1.2 ! misho     318:                title,
1.1       misho     319:                data_fields[j].net_xxx(at),
1.1.1.2 ! misho     320:                title );
1.1       misho     321:       }
                    322:     }
                    323:     printf("    </HUB>\n");
                    324:   }
                    325:   printf("</MTR>\n");
                    326: }
                    327: 
                    328: 
                    329: void csv_open(void)
                    330: {
                    331: }
                    332: 
                    333: void csv_close(time_t now)
                    334: {
                    335:   int i, j, at, max;
                    336:   ip_t *addr;
                    337:   char name[81];
                    338: 
                    339:   for( i=0; i<MAXFLD; i++ ) {
                    340:       j = fld_index[fld_active[i]];
                    341:       if (j < 0) continue; 
                    342:   }
                    343: 
                    344:   max = net_max();
                    345:   at  = net_min();
                    346:   for(; at < max; at++) {
                    347:     addr = net_addr(at);
                    348:     snprint_addr(name, sizeof(name), addr);
                    349: 
                    350:     int last = net_last(at);
1.1.1.2 ! misho     351: #ifdef IPINFO
1.1       misho     352:     if(!ipinfo_no) {
                    353:       char* fmtinfo = fmt_ipinfo(addr);
                    354:       if (fmtinfo != NULL) fmtinfo = trim(fmtinfo);
1.1.1.2 ! misho     355:       printf("MTR.%s;%lld;%s;%s;%d;%s;%s;%d", MTR_VERSION, (long long)now, "OK", Hostname,
1.1       misho     356:              at+1, name, fmtinfo, last);
1.1.1.2 ! misho     357:     } else
        !           358: #endif
        !           359:       printf("MTR.%s;%lld;%s;%s;%d;%s;%d", MTR_VERSION, (long long)now, "OK", Hostname,
1.1       misho     360:              at+1, name, last);
                    361: 
                    362:     for( i=0; i<MAXFLD; i++ ) {
                    363:       j = fld_index[fld_active[j]];
                    364:       if (j < 0) continue; 
                    365: 
                    366:       /* 1000.0 is a temporay hack for stats usec to ms, impacted net_loss. */
                    367:       if( index( data_fields[j].format, 'f' ) ) {
                    368:        printf( ", %.2f", data_fields[j].net_xxx(at) / 1000.0);
                    369:       } else {
                    370:        printf( ", %d",   data_fields[j].net_xxx(at) );
                    371:       }
                    372:     }
                    373:     printf("\n");
                    374:   }
                    375: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>