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>