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>