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

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

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