File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mtr / report.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:43:42 2013 UTC (10 years, 11 months ago) by misho
Branches: mtr, elwix, MAIN
CVS tags: v0_85, HEAD
0.85

    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>