2
* Copyright (C) 1998-2004 Luca Deri <deri@ntop.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
#include "globals-report.h"
24
/* *************************** */
27
static void ignoreSignal(int signalId) {
28
closeNwSocket(&myGlobals.newSock);
29
(void)signal(signalId, ignoreSignal);
33
/* ******************************* */
35
void printBandwidthFooter(void) {
36
sendString("<p><b>NOTE</b>:</p>\n<ul>"
37
"<li>Click <a href=\"" CONST_HOST_SORT_NOTE_HTML "\">here</a> "
38
"for more information about host and domain sorting.</li>\n"
39
"<li>Bandwidth values are the percentage of the total bytes that "
40
"<b>ntop</b> has seen on the interface. Hover the mouse to see the actual "
41
"value (rounded to the nearest full percentage point). <i>The total of the "
42
"values will NOT be 100% as local traffic will be counted TWICE (once as "
43
"sent and again as received).</i></li>\n"
44
"<li>The SENT bandwidth is shown as "
45
"<img align=\"absmiddle\" src=\"/gaugeS.jpg\" alt=\"Sent\" WIDTH=\"25\" HEIGHT=\"12\">"
46
" and the RECEIVED bandwidth is shown as "
47
"<img align=\"absmiddle\" src=\"/gaugeR.jpg\" alt=\"Received\" WIDTH=\"25\" HEIGHT=\"12\"></li>\n"
51
/* ******************************* */
53
void initReports(void) {
55
char value[LEN_SMALL_WORK_BUFFER];
57
myGlobals.columnSort = 0;
58
addDefaultAdminUser();
60
/* Show device table */
61
for(i=0; i<myGlobals.numDevices; i++) {
62
traceEvent(CONST_TRACE_NOISY, "Device %2d. %-30s%s%s%s",
64
myGlobals.device[i].humanFriendlyName != NULL ?
65
myGlobals.device[i].humanFriendlyName :
66
myGlobals.device[i].name,
67
myGlobals.device[i].virtualDevice ? " (virtual)" : "",
68
myGlobals.device[i].dummyDevice ? " (dummy)" : "",
69
myGlobals.device[i].activeDevice ? " (active)" : "");
72
/* Corrections on stored value */
73
if(myGlobals.mergeInterfaces) {
74
traceEvent(CONST_TRACE_NOISY,
75
"INITWEB: Merging interfaces, reporting device forced to 0");
76
storePrefsValue("actualReportDeviceId", "0");
77
} else if(fetchPrefsValue("actualReportDeviceId", value, sizeof(value)) == -1) {
78
traceEvent(CONST_TRACE_NOISY,
79
"INITWEB: Reporting device not set, defaulting to 0");
80
storePrefsValue("actualReportDeviceId", "0");
81
} else if(atoi(value) >= myGlobals.numDevices) {
82
traceEvent(CONST_TRACE_WARNING,
83
"INITWEB: Reporting device (%d) invalid (> max, %d), defaulting to 0");
84
storePrefsValue("actualReportDeviceId", "0");
88
if(fetchPrefsValue("actualReportDeviceId", value, sizeof(value)) == -1) {
89
myGlobals.actualReportDeviceId = 0;
91
myGlobals.actualReportDeviceId = atoi(value);
94
if(myGlobals.device[myGlobals.actualReportDeviceId].virtualDevice) {
95
/* Bad idea, set to 1st non-virtual device */
96
traceEvent(CONST_TRACE_WARNING,
97
"INITWEB: Reporting device (%d) invalid (virtual), using 1st non-virtual device");
98
for(i=0; i<myGlobals.numDevices; i++) {
99
if(!myGlobals.device[i].virtualDevice) {
100
myGlobals.actualReportDeviceId = i;
101
if(snprintf(value, sizeof(value), "%d", i) < 0)
103
storePrefsValue("actualReportDeviceId", value);
109
traceEvent(CONST_TRACE_INFO,
110
"Note: Reporting device initally set to %d [%s]%s",
111
myGlobals.actualReportDeviceId,
112
myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName != NULL ?
113
myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName :
114
myGlobals.device[myGlobals.actualReportDeviceId].name,
115
myGlobals.mergeInterfaces ? " (merged)" : "");
119
/* **************************************** */
121
int reportValues(time_t *lastTime) {
122
if(myGlobals.maxNumLines <= 0)
123
myGlobals.maxNumLines = CONST_NUM_TABLE_ROWS_PER_PAGE;
125
*lastTime = time(NULL) + myGlobals.refreshRate;
128
Make sure that the other flags are't set. They have
129
no effect in web mode
131
if(myGlobals.refreshRate == 0)
132
myGlobals.refreshRate = DEFAULT_NTOP_AUTOREFRESH_INTERVAL;
133
else if(myGlobals.refreshRate < PARM_MIN_WEBPAGE_AUTOREFRESH_TIME)
134
myGlobals.refreshRate = PARM_MIN_WEBPAGE_AUTOREFRESH_TIME;
139
/* ******************************* */
141
void addPageIndicator(char *url, u_int pageNum,
142
u_int numEntries, u_int linesPerPage,
143
int revertOrder, int numCol) {
144
char buf[LEN_GENERAL_WORK_BUFFER/2], prevBuf[LEN_GENERAL_WORK_BUFFER/2], nextBuf[LEN_GENERAL_WORK_BUFFER/2], shortBuf[16], separator;
145
int numPages = (numEntries+myGlobals.maxNumLines-1)/myGlobals.maxNumLines;
146
int actPage = pageNum+1;
148
if(numPages <= 1) return;
150
if(strchr(url, '?') != NULL)
155
if(revertOrder == -1)
158
if(snprintf(shortBuf, sizeof(shortBuf),
159
"%s%d", revertOrder == 1 ? "-" : "", numCol) < 0)
164
if(snprintf(prevBuf, sizeof(prevBuf),
165
"<A HREF=\"%s%cpage=0&col=%s\"><IMG SRC=/fback.gif BORDER=0 "TABLE_DEFAULTS" ALIGN=vmiddle ALT=\"Back to first page\"></A> "
166
"<A HREF=\"%s%cpage=%d&col=%s\"><IMG SRC=/back.gif BORDER=0 "TABLE_DEFAULTS" ALIGN=vmiddle ALT=\"Prior page\"></A>",
167
url, separator, shortBuf, url, separator, pageNum-1, shortBuf) < 0)
172
if(actPage < numPages) {
173
if(snprintf(nextBuf, sizeof(nextBuf),
174
"<A HREF=\"%s%cpage=%d&col=%s\"><IMG SRC=/forward.gif BORDER=0 "TABLE_DEFAULTS" ALIGN=vmiddle ALT=\"Next Page\"></A> "
175
"<A HREF=\"%s%cpage=%d&col=%s\"><IMG SRC=/fforward.gif BORDER=0 "TABLE_DEFAULTS" ALIGN=vmiddle ALT=\"Forward to last page\"></A>",
176
url, separator, pageNum+1, shortBuf, url, separator, numPages-1, shortBuf) < 0)
181
sendString("<P><FONT FACE=Helvetica><B>");
184
if(snprintf(buf, sizeof(buf), " [ %d / %d ] ", actPage, numPages) < 0)
189
sendString("</B></FONT>\n");
192
/* ******************************* */
194
void printTrafficStatistics(int revertOrder) {
195
Counter unicastPkts, avgPktLen;
197
char buf[LEN_GENERAL_WORK_BUFFER], formatBuf[32], formatBuf1[32];
199
struct pcap_stat pcapStat;
202
printHTMLheader("Global Traffic Statistics", NULL, 0);
204
sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n");
206
sendString("<TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG">Network Interface(s)</TH>"
207
"<TD "TD_BG" ALIGN=RIGHT>");
209
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\">\n<TR "TR_ON" "DARK_BG"><TH "TH_BG" "DARK_BG">Name</TH>"
210
"<TH "TH_BG" "DARK_BG">Device</TH><TH "TH_BG" "DARK_BG">Type</TH>"
211
"<TH "TH_BG" "DARK_BG">Speed</TH><TH "TH_BG" "DARK_BG">MTU</TH>"
212
"<TH "TH_BG" "DARK_BG">Header</TH><TH "TH_BG" "DARK_BG">Address</TH>");
215
sendString("<TH "TH_BG" "DARK_BG">IPv6 Addresses</TH></TR>\n");
218
if(myGlobals.rFileName == NULL) {
219
for(i=0; i<myGlobals.numDevices; i++) {
220
if(myGlobals.device[i].activeDevice) {
222
NtopIfaceAddr *ifaddr;
224
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" ALIGN=CENTER><TD "TD_BG">%s</TD>",
225
myGlobals.device[i].humanFriendlyName[0] != '\0'
226
? myGlobals.device[i].humanFriendlyName : " ") < 0)
230
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%s</TD>",
231
myGlobals.device[i].name) < 0)
235
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%s%s</TD>",
236
getNwInterfaceType(i), myGlobals.device[i].virtualDevice ? " virtual" : "") < 0)
240
sendString("<TD "TD_BG" ALIGN=RIGHT nowrap> ");
241
if(myGlobals.device[i].deviceSpeed > 0) {
242
/* The speed is known */
243
sendString(formatAdapterSpeed(myGlobals.device[i].deviceSpeed, formatBuf, sizeof(formatBuf)));
245
sendString(" ");
248
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%d</TD>",
249
myGlobals.mtuSize[myGlobals.device[i].datalink]) < 0)
253
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%d</TD>",
254
myGlobals.headerSize[myGlobals.device[i].datalink]) < 0)
258
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%s</TD>",
259
_intoa(myGlobals.device[i].ifAddr, buf1, sizeof(buf1))) < 0)
264
sendString("<TD ALIGN=LEFT>");
265
if(myGlobals.device[i].v6Addrs > 0) {
266
for(ifaddr = myGlobals.device[i].v6Addrs;
267
ifaddr != NULL; ifaddr = ifaddr->next) {
268
if(snprintf(buf, sizeof(buf), "%s/%d<br>",
269
_intop(&ifaddr->af.inet6.ifAddr, buf1, sizeof(buf1)),
270
ifaddr->af.inet6.prefixlen) < 0)
275
sendString(" ");
279
sendString("</TR>\n");
283
if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TD "TD_BG" ALIGN=CENTER>%s</TD><TD "TD_BG"> </TD>",
284
CONST_PCAP_NW_INTERFACE_FILE) < 0)
288
sendString("<TD "TD_BG" ALIGN=CENTER>");
290
if(strlen(myGlobals.rFileName) < 64)
291
sendString(myGlobals.rFileName);
293
for(i=strlen(myGlobals.rFileName); i>0; i--)
294
if((myGlobals.rFileName[i] == '/')
295
|| (myGlobals.rFileName[i] == '\\'))
298
if(snprintf(buf, sizeof(buf), "...%s", &myGlobals.rFileName[i]) < 0)
304
sendString("<TD "TD_BG"> </TD>");
305
sendString("<TD "TD_BG"> </TD>");
306
sendString("<TD "TD_BG"> </TD>");
307
sendString("<TD "TD_BG"> </TD>");
309
sendString("<TD "TD_BG"> </TD>");
311
sendString("</TR>\n");
314
sendString("</TABLE>"TABLE_OFF);
315
sendString("</TD></TR>\n");
317
if(myGlobals.domainName[0] != '\0') {
318
if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG">Local Domain Name</TH>"
319
"<TD "TD_BG" ALIGN=RIGHT>%s </TD></TR>\n",
320
myGlobals.domainName) < 0)
325
if (myGlobals.rFileName == NULL) {
326
if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG">Sampling Since</TH>"
327
"<TD "TD_BG" ALIGN=RIGHT>%s [%s]</TD></TR>\n",
328
ctime(&myGlobals.initialSniffTime),
329
formatSeconds(time(NULL)-myGlobals.initialSniffTime, formatBuf, sizeof(formatBuf))) < 0)
334
if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG">Sampling Since</TH>"
335
"<TD "TD_BG" ALIGN=RIGHT>%s</TD></TR>\n",
336
ctime(&myGlobals.initialSniffTime)) < 0)
340
if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TH "TH_BG" align=left "DARK_BG">Last Packet Seen</TH>"
341
"<TD "TD_BG" ALIGN=RIGHT>%s [%s]</TD></TR>\n",
342
ctime((time_t *)&myGlobals.lastPktTime),
343
formatSeconds(myGlobals.lastPktTime.tv_sec-myGlobals.initialSniffTime, formatBuf, sizeof(formatBuf))) < 0)
348
if((i = numActiveSenders(myGlobals.actualReportDeviceId)) > 0) {
349
if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG">Active End Nodes</TH>"
350
"<TD "TD_BG" ALIGN=RIGHT>%u</TD></TR>\n", i) < 0)
355
if((myGlobals.currentFilterExpression != NULL)
356
&& (myGlobals.currentFilterExpression[0] != '\0')) {
357
if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG">Traffic Filter</TH>"
358
"<TD "TD_BG" ALIGN=RIGHT>%s</TD></TR>\n",
359
myGlobals.currentFilterExpression) < 0)
365
if(myGlobals.numRealDevices > 1)
366
sendString("<TR "TR_ON"><TD "TD_BG" ALIGN=CENTER COLSPAN=3 BGCOLOR=white>"
367
"<IMG SRC=\"" CONST_PIE_INTERFACE_DIST CHART_FORMAT "\" "
368
"alt=\"interface traffic chart\"></TD></TR>\n");
371
if(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value > 0) {
372
Counter dummyCounter;
374
sendString("</TABLE>"TABLE_OFF"</CENTER>\n");
375
if(snprintf(buf, sizeof(buf),
376
"For device: '%s' (current reporting device)",
377
myGlobals.device[myGlobals.actualReportDeviceId].name) < 0)
379
printSectionTitle(buf);
380
sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n");
382
sendString("<TR><TH "TH_BG" align=left "DARK_BG">Packets</TH><TD "TH_BG">\n"
383
"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\">\n");
385
unicastPkts = myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value
386
- myGlobals.device[myGlobals.actualReportDeviceId].broadcastPkts.value
387
- myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value;
389
if(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value <= 0)
390
myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value = 1;
392
if(myGlobals.device[myGlobals.actualReportDeviceId].pcapPtr != NULL) {
393
if(pcap_stats(myGlobals.device[myGlobals.actualReportDeviceId].pcapPtr, &pcapStat) >= 0) {
395
Recent libpcap versions do not report total/cumulative values
396
but their value is reset everytime is read
399
if(myGlobals.device[myGlobals.actualReportDeviceId].receivedPkts.value > pcapStat.ps_recv) {
400
/* The counter is reset at each run */
401
myGlobals.device[myGlobals.actualReportDeviceId].pcapDroppedPkts.value += pcapStat.ps_drop;
403
/* The counter is NOT reset at each run */
404
myGlobals.device[myGlobals.actualReportDeviceId].pcapDroppedPkts.value = pcapStat.ps_drop;
407
if(snprintf(buf, sizeof(buf),
408
"<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Dropped (libpcap)</th>"
409
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
411
(float)(myGlobals.device[myGlobals.actualReportDeviceId].pcapDroppedPkts.value*100)
412
/(float)myGlobals.device[myGlobals.actualReportDeviceId].receivedPkts.value,
413
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].pcapDroppedPkts.value,
414
formatBuf, sizeof(formatBuf))) < 0)
420
if(snprintf(buf, sizeof(buf),
421
"<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Dropped (ntop)</th>"
422
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
424
(float)(myGlobals.device[myGlobals.actualReportDeviceId].droppedPkts.value*100)
425
/(float)myGlobals.device[myGlobals.actualReportDeviceId].receivedPkts.value,
426
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].droppedPkts.value,
427
formatBuf, sizeof(formatBuf))) < 0)
431
if(snprintf(buf, sizeof(buf),
432
"<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Total Received (ntop)</th>"
433
"<TD "TD_BG" COLSPAN=2 align=right>%s</td></TR>\n",
434
getRowColor(), formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].receivedPkts.value,
435
formatBuf, sizeof(formatBuf))) < 0)
440
if(snprintf(buf, sizeof(buf),
441
"<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Total Packets Processed</th>"
442
"<TD "TD_BG" COLSPAN=2 align=right>%s</td></TR>\n",
443
getRowColor(), formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
444
formatBuf, sizeof(formatBuf))) < 0)
448
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Unicast</th>"
449
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
450
getRowColor(), (float)(100*unicastPkts)/(float)myGlobals.device[myGlobals.actualReportDeviceId].
452
formatPkts(unicastPkts, formatBuf, sizeof(formatBuf))) < 0) BufferTooShort();
454
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Broadcast</th>"
455
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
456
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].broadcastPkts.value)/
457
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
458
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].broadcastPkts.value, formatBuf, sizeof(formatBuf))) < 0)
462
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Multicast</th>"
463
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
464
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value)/
465
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
466
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value, formatBuf, sizeof(formatBuf))) < 0)
471
if(myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value > 0)
472
sendString("<TR "TR_ON" BGCOLOR=white><TH BGCOLOR=white ALIGN=CENTER COLSPAN=3>"
473
"<IMG SRC=\"" CONST_PIE_PKT_CAST_DIST CHART_FORMAT "\" "
474
"alt=\"pktCast distribution chart\"></TH></TR>\n");
477
if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
479
Very rudimental formula. Note that as specified in RMON, packets smaller
480
than 64 or larger than 1518 octets are not counted.
482
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Shortest</th>"
483
"<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
485
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.shortest.value, formatBuf, sizeof(formatBuf))) < 0)
488
avgPktLen = (96*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo128.value
489
+192*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo256.value
490
+384*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo512.value
491
+768*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo1024.value
492
+1271*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo1518.value)/
493
(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value+1);
494
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Average Size</th>"
495
"<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
496
getRowColor(), formatPkts(avgPktLen, formatBuf, sizeof(formatBuf))) < 0)
499
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Longest</th>"
500
"<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
501
getRowColor(), formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].
502
rcvdPktStats.longest.value, formatBuf, sizeof(formatBuf))) < 0)
506
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">< 64 bytes</th>"
507
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
508
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
509
rcvdPktStats.upTo64.value)/
510
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
511
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo64.value, formatBuf, sizeof(formatBuf))) < 0)
514
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">< 128 bytes</th>"
515
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
516
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
517
rcvdPktStats.upTo128.value)/
518
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
519
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo128.value, formatBuf, sizeof(formatBuf))) < 0)
522
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">< 256 bytes</th>"
523
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
524
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
525
rcvdPktStats.upTo256.value)/
526
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
527
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo256.value, formatBuf, sizeof(formatBuf))) < 0)
530
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">< 512 bytes</th>"
531
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
532
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
533
rcvdPktStats.upTo512.value)/
534
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
535
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo512.value, formatBuf, sizeof(formatBuf))) < 0)
538
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">< 1024 bytes</th>"
539
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
540
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
541
rcvdPktStats.upTo1024.value)/
542
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
543
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo1024.value, formatBuf, sizeof(formatBuf))) < 0)
546
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">< 1518 bytes</th>"
547
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
548
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
549
rcvdPktStats.upTo1518.value)/
550
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
551
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.upTo1518.value, formatBuf, sizeof(formatBuf))) < 0)
554
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">> 1518 bytes</th>"
555
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
556
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
557
rcvdPktStats.above1518.value)/
558
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
559
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.above1518.value, formatBuf, sizeof(formatBuf))) < 0)
564
if(myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value > 0)
565
sendString("<TR "TR_ON" BGCOLOR=white><TH "TH_BG" ALIGN=CENTER COLSPAN=3 BGCOLOR=white>"
566
"<IMG SRC=\"" CONST_PIE_PKT_SIZE_DIST CHART_FORMAT "\" "
567
"alt=\"pktSize distribution chart\"></TH></TR>\n");
570
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Packets too long [> %d]</th>"
571
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
572
getRowColor(), myGlobals.mtuSize[myGlobals.device[myGlobals.actualReportDeviceId].datalink],
573
(float)(100*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.tooLong.value)/
574
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
575
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.tooLong.value, formatBuf, sizeof(formatBuf))) < 0)
579
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Bad Packets (Checksum)</th>"
580
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
581
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
582
rcvdPktStats.badChecksum.value)/
583
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
584
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.badChecksum.value, formatBuf, sizeof(formatBuf))) < 0)
589
/* ****************** */
591
if(!myGlobals.noFc &&
592
myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value > 0) {
593
sendString("</TABLE>"TABLE_OFF"</TR><TR><TH "TH_BG" ALIGN=LEFT "DARK_BG">FC Packets</TH><TD "TH_BG">\n<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\">");
595
if(myGlobals.device[myGlobals.actualReportDeviceId].pcapPtr != NULL) {
596
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Total</th>"
597
"<TD "TD_BG" align=right COLSPAN=2>%s [%s Pkts]</td></TR>\n",
599
formatBytes(myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value, 1,
600
formatBuf, sizeof (formatBuf)),
601
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
602
formatBuf1, sizeof (formatBuf1))) < 0)
606
if(myGlobals.device[myGlobals.actualReportDeviceId].droppedPkts.value > 0) {
607
if(snprintf(buf, sizeof(buf),
608
"<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Dropped by the kernel</th>"
609
"<TD "TD_BG" COLSPAN=2 align=right>%s [%.2f %%]</td></TR>\n",
611
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].droppedPkts.value,
612
formatBuf, sizeof (formatBuf)),
613
(float)(myGlobals.device[myGlobals.actualReportDeviceId].droppedPkts.value*100)
614
/(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value) < 0)
621
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Unicast</th>"
622
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
623
getRowColor(), (float)(100*unicastPkts)/(float)myGlobals.device[myGlobals.actualReportDeviceId].
625
formatPkts(unicastPkts, formatBuf, sizeof (formatBuf))) < 0) BufferTooShort();
627
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Broadcast</th>"
628
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
629
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].fcBroadcastPkts.value)/
630
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
631
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].fcBroadcastPkts.value,
632
formatBuf, sizeof (formatBuf))) < 0)
636
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Shortest</th>"
637
"<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
639
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.shortest.value,
640
formatBuf, sizeof (formatBuf))) < 0)
644
avgPktLen = myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value/
645
myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value;
646
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Average Size</th>"
647
"<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
648
getRowColor(), formatPkts(avgPktLen, formatBuf, sizeof (formatBuf))) < 0)
652
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Longest</th>"
653
"<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
654
getRowColor(), formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].
655
rcvdFcPktStats.longest.value, formatBuf,
656
sizeof (formatBuf))) < 0)
660
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&le 36 bytes</th>"
661
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
662
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
663
rcvdFcPktStats.upTo36.value)/
664
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
665
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo36.value,
666
formatBuf, sizeof (formatBuf))) < 0)
670
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>≤ 48 bytes</th>"
671
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
672
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
673
rcvdFcPktStats.upTo48.value)/
674
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
675
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo48.value,
676
formatBuf, sizeof (formatBuf))) < 0)
680
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>≤ 52 bytes</th>"
681
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
682
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
683
rcvdFcPktStats.upTo52.value)/
684
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
685
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo52.value,
686
formatBuf, sizeof (formatBuf))) < 0)
690
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>≤ 68 bytes</th>"
691
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
692
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
693
rcvdFcPktStats.upTo68.value)/
694
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
695
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo68.value,
696
formatBuf, sizeof (formatBuf))) < 0)
700
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>≤ 104 bytes</th>"
701
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
702
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
703
rcvdFcPktStats.upTo104.value)/
704
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
705
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo104.value,
706
formatBuf, sizeof (formatBuf))) < 0)
709
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>≤ 548 bytes</th>"
710
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
711
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
712
rcvdFcPktStats.upTo548.value)/
713
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
714
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo548.value,
715
formatBuf, sizeof (formatBuf))) < 0)
718
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>≤ 1060 bytes</th>"
719
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
720
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
721
rcvdFcPktStats.upTo1060.value)/
722
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
723
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo1060.value,
724
formatBuf, sizeof (formatBuf))) < 0)
728
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>≤ 2136 bytes</th>"
729
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
730
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
731
rcvdFcPktStats.upTo2136.value)/
732
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
733
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.upTo2136.value,
734
formatBuf, sizeof (formatBuf))) < 0)
738
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>> 2136 bytes</th>"
739
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
740
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
741
rcvdFcPktStats.above2136.value)/
742
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
743
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.above2136.value,
744
formatBuf, sizeof (formatBuf))) < 0)
748
sendString("<TR "TR_ON" BGCOLOR=white><TH "TH_BG" "DARK_BG" ALIGN=CENTER COLSPAN=3 BGCOLOR=white>"
749
"<IMG SRC=\"" CONST_PIE_FC_PKT_SZ_DIST CHART_FORMAT"\" alt=\"FC pktSize distribution chart\"></TH></TR>\n");
751
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>Packets too long [> %d]</th>"
752
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
754
(float)(100*myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.above2136.value)/
755
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
756
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.above2136.value,
757
formatBuf, sizeof (formatBuf))) < 0)
761
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>Bad EOF Frames</th>"
762
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
763
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
764
rcvdFcPktStats.badCRC.value)/
765
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcPkts.value,
766
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.badCRC.value,
767
formatBuf, sizeof (formatBuf))) < 0)
772
/* ****************** */
774
sendString("</TABLE>"TABLE_OFF"</TR><TR><TH "TH_BG" ALIGN=LEFT "DARK_BG">Traffic</TH><TD "TH_BG">\n<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\">");
775
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Total</th>"
776
"<TD "TD_BG" align=right COLSPAN=2>%s [%s Pkts]</td></TR>\n",
778
formatBytes(myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value, 1, formatBuf, sizeof(formatBuf)),
779
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value, formatBuf, sizeof(formatBuf))) < 0)
783
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">IP Traffic</th>"
784
"<TD "TD_BG" align=right COLSPAN=2>%s [%s Pkts]</td></TR>\n",
785
getRowColor(), formatBytes(myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value, 1, formatBuf, sizeof(formatBuf)),
786
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].ipPkts.value, formatBuf, sizeof(formatBuf))) < 0)
790
if(myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value > 0) {
791
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Fragmented IP Traffic</th>"
792
"<TD "TD_BG" align=right COLSPAN=2>%s [%.1f%%]</td></TR>\n",
794
formatBytes(myGlobals.device[myGlobals.actualReportDeviceId].fragmentedIpBytes.value, 1, formatBuf, sizeof(formatBuf)),
795
(float)(100*myGlobals.device[myGlobals.actualReportDeviceId].fragmentedIpBytes.value)/
796
(float)myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value) < 0)
801
/* Just in case... */
802
if(myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value >
803
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value)
804
dummyCounter = myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value-
805
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value;
809
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Non IP Traffic</th>"
810
"<TD "TD_BG" align=right COLSPAN=2>%s</td></TR>\n",
811
getRowColor(), formatBytes(dummyCounter, 1, formatBuf, sizeof(formatBuf))) < 0)
816
if(myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value > 0)
817
sendString("<TR "TR_ON" BGCOLOR=white><TH BGCOLOR=white ALIGN=CENTER COLSPAN=3>"
818
"<IMG SRC=\"" CONST_PIE_IP_TRAFFIC CHART_FORMAT "\" alt=\"ipTraffic chart\"></TH></TR>\n");
821
/* ********************* */
823
if(myGlobals.device[myGlobals.actualReportDeviceId].ipPkts.value > 0) {
826
avgPktTTL = (int)((16*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo32.value
827
+48*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo64.value
828
+80*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo96.value
829
+112*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo128.value
830
+144*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo160.value
831
+176*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo192.value
832
+208*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo224.value
833
+240*myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo255.value)/
834
myGlobals.device[myGlobals.actualReportDeviceId].ipPkts.value);
837
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Average TTL</th>"
838
"<TD "TD_BG" align=right COLSPAN=2>%d</td></TR>\n",
839
getRowColor(), avgPktTTL) < 0)
842
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">TTL < 32</th>"
843
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
844
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
845
rcvdPktTTLStats.upTo32.value)/
846
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
847
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo32.value,
848
formatBuf, sizeof(formatBuf))) < 0)
851
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">32 < TTL < 64</th>"
852
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
853
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
854
rcvdPktTTLStats.upTo64.value)/
855
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
856
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo64.value,
857
formatBuf, sizeof(formatBuf))) < 0)
860
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">64 < TTL < 96</th>"
861
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
862
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
863
rcvdPktTTLStats.upTo96.value)/
864
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
865
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo96.value,
866
formatBuf, sizeof(formatBuf))) < 0)
869
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">96 < TTL < 128</th>"
870
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
871
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
872
rcvdPktTTLStats.upTo128.value)/
873
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
874
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo128.value,
875
formatBuf, sizeof(formatBuf))) < 0)
878
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">128 < TTL < 160</th>"
879
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
880
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
881
rcvdPktTTLStats.upTo160.value)/
882
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
883
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo160.value,
884
formatBuf, sizeof(formatBuf))) < 0)
887
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">160 < TTL < 192</th>"
888
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
889
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
890
rcvdPktTTLStats.upTo192.value)/
891
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
892
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo192.value,
893
formatBuf, sizeof(formatBuf))) < 0)
896
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">192 < TTL < 224</th>"
897
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
898
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
899
rcvdPktTTLStats.upTo224.value)/
900
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
901
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo224.value,
902
formatBuf, sizeof(formatBuf))) < 0)
905
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">224 < TTL < 256</th>"
906
"<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
907
getRowColor(), (float)(100*myGlobals.device[myGlobals.actualReportDeviceId].
908
rcvdPktTTLStats.upTo255.value)/
909
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value,
910
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktTTLStats.upTo255.value,
911
formatBuf, sizeof(formatBuf))) < 0)
916
sendString("<TR "TR_ON"><TH BGCOLOR=white COLSPAN=3>"
917
"<IMG SRC=\"" CONST_PIE_TTL_DIST CHART_FORMAT "\" "
918
"alt=\"pktTTD distribution chart\"></TH></TR>\n");
923
sendString("</TABLE>"TABLE_OFF"</TR>");
924
/* ************************ */
927
if(myGlobals.enableSessionHandling && drawHostsDistanceGraph(1))
928
sendString("<TR><TH "TH_BG" ALIGN=LEFT "DARK_BG">Remote Hosts Distance</TH>"
929
"<TD BGCOLOR=white ALIGN=CENTER>"
930
"<IMG SRC=\"" CONST_BAR_HOST_DISTANCE CHART_FORMAT "\" "
931
"alt=\"hosts distance chart\"></TD></TR>\n");
934
if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
937
sendString("<TR><TH "TH_BG" ALIGN=LEFT "DARK_BG">Network Load</TH><TD "TH_BG">\n<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\">");
938
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Actual</th><TD "TD_BG" align=right>%s</td>"
939
"<TD "TD_BG" align=right>%.1f Pkts/sec</td></TR>\n",
940
getRowColor(), formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].actualThpt,
941
1, formatBuf, sizeof(formatBuf)),
942
myGlobals.device[myGlobals.actualReportDeviceId].actualPktsThpt, 1) < 0)
945
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Last Minute</th>"
946
"<TD "TD_BG" align=right>%s</td>"
947
"<TD "TD_BG" align=right>%.1f Pkts/sec</td></TR>\n",
948
getRowColor(), formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].lastMinThpt,
949
1, formatBuf, sizeof(formatBuf)),
950
myGlobals.device[myGlobals.actualReportDeviceId].lastMinPktsThpt, 1) < 0)
954
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Last 5 Minutes</th>"
955
"<TD "TD_BG" align=right>%s</td>"
956
"<TD "TD_BG" align=right>%.1f Pkts/sec</td></TR>\n",
957
getRowColor(), formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].lastFiveMinsThpt,
958
1, formatBuf, sizeof(formatBuf)),
959
myGlobals.device[myGlobals.actualReportDeviceId].lastFiveMinsPktsThpt, 1) < 0)
963
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Peak</th>"
964
"<TD "TD_BG" align=right>%s</td>"
965
"<TD "TD_BG" align=right>%.1f Pkts/sec</td></TR>\n",
966
getRowColor(), formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].peakThroughput,
967
1, formatBuf, sizeof(formatBuf)),
968
myGlobals.device[myGlobals.actualReportDeviceId].peakPacketThroughput) < 0)
972
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Average</th>"
973
"<TD "TD_BG" align=right>%s</td>"
974
"<TD "TD_BG" align=right>%.1f Pkts/sec</td></TR>\n",
976
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value/
977
(myGlobals.actTime-myGlobals.initialSniffTime+1), 1, formatBuf, sizeof(formatBuf)),
978
/* Bug below fixed courtesy of Eddy Lai <eddy@ModernTerminals.com> */
979
((float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value/
980
(float)(myGlobals.actTime-myGlobals.initialSniffTime+1))) < 0)
984
sendString("</TABLE>"TABLE_OFF"</TR>\n");
988
/* ********************* */
992
/* Do NOT add a '/' at the end of the path because Win32 will complain about it */
993
if(snprintf(buf, sizeof(buf), "%s/interfaces/%s",
994
myGlobals.rrdPath != NULL ? myGlobals.rrdPath : ".",
995
myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName) < 0)
998
if((i = stat(buf, &statbuf)) == 0) {
999
if(snprintf(buf, sizeof(buf),
1000
"<TR %s><TH "TH_BG" ALIGN=LEFT "DARK_BG">Historical Data</TH>\n"
1001
"<TD "TD_BG" align=\"right\">"
1002
"[ <a href=\"/" CONST_PLUGINS_HEADER
1003
"rrdPlugin?action=list&key=interfaces/%s&title=interface%%20%s\">"
1004
"<img valign=\"top\" border=\"0\" src=\"/graph.gif\""
1005
" alt=\"View rrd charts of historical data for this interface\"></a> ]"
1007
getRowColor(), myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName,
1008
myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName) < 0)
1013
/* ********************* */
1015
sendString("</TABLE></CENTER>\n");
1017
if (!myGlobals.printFcOnly) {
1018
printProtoTraffic();
1019
sendString("<p>\n");
1020
printIpProtocolDistribution(FLAG_HOSTLINK_HTML_FORMAT, revertOrder);
1022
if (!myGlobals.noFc) {
1023
sendString("<p>\n");
1024
printFcProtocolDistribution(FLAG_HOSTLINK_HTML_FORMAT, revertOrder);
1028
/* ******************************* */
1030
int combineReportTypeLocality(int reportTypeReq, LocalityDisplayPolicy showLocalityMode) {
1035
switch(reportTypeReq) {
1036
case SORT_DATA_HOST_TRAFFIC:
1037
switch(showLocalityMode) {
1039
rc = SORT_DATA_SENT_HOST_TRAFFIC;
1041
case showOnlyReceived:
1042
rc = SORT_DATA_RCVD_HOST_TRAFFIC;
1045
case SORT_DATA_PROTOS:
1046
switch(showLocalityMode) {
1048
rc = SORT_DATA_SENT_PROTOS;
1050
case showOnlyReceived:
1051
rc = SORT_DATA_RECEIVED_PROTOS;
1055
switch(showLocalityMode) {
1057
rc = SORT_DATA_SENT_IP;
1059
case showOnlyReceived:
1060
rc = SORT_DATA_RECEIVED_IP;
1063
case SORT_DATA_THPT:
1064
switch(showLocalityMode) {
1066
rc = SORT_DATA_SENT_THPT;
1068
case showOnlyReceived:
1069
rc = SORT_DATA_RECEIVED_THPT;
1078
/* ******************************* */
1080
void printHostsTraffic(int reportTypeReq,
1085
HostsDisplayPolicy showHostsMode,
1086
LocalityDisplayPolicy showLocalityMode) {
1087
u_int idx, idx1, numEntries=0;
1088
int printedEntries=0, hourId, maxHosts;
1092
HostTraffic** tmpTable;
1093
char buf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
1094
float sentPercent=0, rcvdPercent=0, totPercent=0;
1095
Counter totIpBytesSent=0, totIpBytesRcvd=0, totIpBytes=0;
1096
Counter totEthBytesSent=0, totEthBytesRcvd=0, totEthBytes=0;
1097
ProtocolsList *protoList;
1098
char formatBuf[32], formatBuf1[32], formatBuf2[32], formatBuf3[32],
1099
formatBuf4[32], formatBuf5[32], formatBuf6[32], formatBuf7[32],
1100
formatBuf8[32], formatBuf9[32];
1103
reportType=combineReportTypeLocality(reportTypeReq, showLocalityMode);
1105
memset(buf, 0, sizeof(buf));
1106
switch(reportType) {
1107
case SORT_DATA_RCVD_HOST_TRAFFIC:
1108
case SORT_DATA_SENT_HOST_TRAFFIC:
1109
case SORT_DATA_HOST_TRAFFIC:
1110
if(snprintf(buf, sizeof(buf), "Network Activity: ") < 0)
1113
case SORT_DATA_RECEIVED_PROTOS:
1114
case SORT_DATA_SENT_PROTOS:
1115
case SORT_DATA_PROTOS:
1116
if(snprintf(buf, sizeof(buf), "Network Traffic [All Protocols]: ") < 0)
1119
case SORT_DATA_RECEIVED_IP:
1120
case SORT_DATA_SENT_IP:
1122
if(snprintf(buf, sizeof(buf), "Network Traffic [TCP/IP]: ") < 0)
1125
case SORT_DATA_RECEIVED_THPT:
1126
case SORT_DATA_SENT_THPT:
1127
case SORT_DATA_THPT:
1128
if(snprintf(buf, sizeof(buf), "Network Throughput: ") < 0)
1132
if(snprintf(buf, sizeof(buf), "?: ") < 0)
1137
switch(showHostsMode) {
1139
strncat(buf, "All Hosts", (sizeof(buf) - strlen(buf) - 1));
1141
case showOnlyLocalHosts:
1142
strncat(buf, "Local Hosts", (sizeof(buf) - strlen(buf) - 1));
1144
case showOnlyRemoteHosts:
1145
strncat(buf, "Remote Hosts", (sizeof(buf) - strlen(buf) - 1));
1149
switch(showLocalityMode) {
1150
case showSentReceived:
1151
strncat(buf, " - Data Sent+Received", (sizeof(buf) - strlen(buf) - 1));
1154
strncat(buf, " - Data Sent", (sizeof(buf) - strlen(buf) - 1));
1156
case showOnlyReceived:
1157
strncat(buf, " - Data Received", (sizeof(buf) - strlen(buf) - 1));
1161
printHTMLheader(buf, NULL, 0);
1162
printHeader(reportTypeReq, revertOrder, abs(sortedColumn), showHostsMode, showLocalityMode);
1164
strftime(theDate, 8, CONST_TOD_HOUR_TIMESPEC, localtime_r(&myGlobals.actTime, &t));
1165
hourId = atoi(theDate);
1167
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno;
1168
/* save ths as it can change */
1170
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*),
1171
"printHostsTraffic");
1172
if(tmpTable == NULL)
1175
for(el=getFirstHost(myGlobals.actualReportDeviceId);
1176
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
1177
if(!isFcHost (el) && (broadcastHost(el) == 0)) {
1180
if(((showLocalityMode == showOnlySent) && (el->bytesSent.value > 0))
1181
|| ((showLocalityMode == showOnlyReceived) && (el->bytesRcvd.value > 0))
1182
|| ((showLocalityMode == showSentReceived) && (el->bytesSent.value + el->bytesRcvd.value > 0))) {
1183
if(((reportType == SORT_DATA_RECEIVED_IP)
1184
|| (reportType == SORT_DATA_SENT_IP)
1185
|| (reportType == SORT_DATA_IP))
1186
&& (el->hostNumIpAddress[0] == '\0')) {
1192
switch(myGlobals.hostsDisplayPolicy) {
1193
case showOnlyLocalHosts:
1194
if(!subnetPseudoLocalHost(el)) addHost = 0;
1196
case showOnlyRemoteHosts:
1197
if(subnetPseudoLocalHost(el)) addHost = 0;
1202
tmpTable[numEntries++] = el;
1203
if(numEntries >= maxHosts)
1210
if(numEntries > 0) {
1212
The switch below is needed to:
1213
- sort data according to the selected column
1214
- 'recycle' (somebody would call this "code reuse") the cmpFctn function
1217
if(sortedColumn == FLAG_HOST_DUMMY_IDX)
1218
myGlobals.columnSort = FLAG_HOST_DUMMY_IDX; /* Host name */
1219
else if(sortedColumn == FLAG_DOMAIN_DUMMY_IDX)
1220
myGlobals.columnSort = FLAG_DOMAIN_DUMMY_IDX; /* domain name */
1222
myGlobals.columnSort = sortedColumn;
1225
traceEvent(CONST_TRACE_INFO, ">reportType=%d/sortedColumn=%d/myGlobals.columnSort=%d<",
1226
reportType, sortedColumn, myGlobals.columnSort);
1229
myGlobals.reportKind = reportType;
1230
/* if(myGlobals.columnSort == 0) myGlobals.reportKind = 0;*/
1232
qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpFctn);
1234
switch(reportType) {
1235
case SORT_DATA_RECEIVED_PROTOS:
1236
case SORT_DATA_SENT_PROTOS:
1237
totEthBytesSent = totEthBytesRcvd = 0;
1239
for(idx=0; idx<numEntries; idx++) {
1240
if(tmpTable[idx] != NULL) {
1241
totEthBytesSent += tmpTable[idx]->bytesSent.value;
1242
totEthBytesRcvd += tmpTable[idx]->bytesRcvd.value;
1246
/* Avoid core dumps */
1247
if(totEthBytesSent == 0) totEthBytesSent = 1;
1248
if(totEthBytesRcvd == 0) totEthBytesRcvd = 1;
1250
case SORT_DATA_PROTOS:
1253
for(idx=0; idx<numEntries; idx++) {
1254
if(tmpTable[idx] != NULL) {
1255
totEthBytes += tmpTable[idx]->bytesSent.value +
1256
tmpTable[idx]->bytesRcvd.value;
1260
/* Avoid core dumps */
1261
if(totEthBytes == 0) totEthBytes = 1;
1263
case SORT_DATA_RECEIVED_IP:
1264
case SORT_DATA_SENT_IP:
1265
totIpBytesSent = totIpBytesRcvd = 0;
1267
for(idx=0; idx<numEntries; idx++) {
1268
if(tmpTable[idx] != NULL) {
1269
totIpBytesSent += tmpTable[idx]->ipBytesSent.value;
1270
totIpBytesRcvd += tmpTable[idx]->ipBytesRcvd.value;
1274
/* Avoid core dumps */
1275
if(totIpBytesSent == 0) totIpBytesSent = 1;
1276
if(totIpBytesRcvd == 0) totIpBytesRcvd = 1;
1281
for(idx=0; idx<numEntries; idx++) {
1282
if(tmpTable[idx] != NULL) {
1283
totIpBytes += tmpTable[idx]->ipBytesSent.value +
1284
tmpTable[idx]->ipBytesRcvd.value;
1288
/* Avoid core dumps */
1289
if(totIpBytes == 0) totIpBytes = 1;
1294
traceEvent(CONST_TRACE_INFO, "totIpBytesSent=%u, totIpBytesRcvd=%u totIpBytes=%u",
1295
totIpBytesSent, totIpBytesRcvd, totIpBytes);
1298
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
1300
char webHostName[LEN_GENERAL_WORK_BUFFER];
1303
el = tmpTable[numEntries-idx-1];
1308
switch(reportType) {
1309
case SORT_DATA_RECEIVED_PROTOS:
1310
case SORT_DATA_SENT_PROTOS:
1311
sentPercent = (100*(float)el->bytesSent.value)/totEthBytesSent;
1312
rcvdPercent = (100*(float)el->bytesRcvd.value)/totEthBytesRcvd;
1314
case SORT_DATA_PROTOS:
1315
totPercent = (100*(float) (el->bytesSent.value + el->bytesRcvd.value) )/totEthBytes;
1317
case SORT_DATA_RECEIVED_IP:
1318
case SORT_DATA_SENT_IP:
1319
sentPercent = (100*(float)el->ipBytesSent.value)/totIpBytesSent;
1320
rcvdPercent = (100*(float)el->ipBytesRcvd.value)/totIpBytesRcvd;
1323
totPercent = (100*(float) (el->ipBytesSent.value + el->ipBytesRcvd.value) )/totIpBytes;
1325
case SORT_DATA_RECEIVED_THPT:
1326
case SORT_DATA_RCVD_HOST_TRAFFIC:
1327
case SORT_DATA_SENT_HOST_TRAFFIC:
1328
case SORT_DATA_SENT_THPT:
1330
case SORT_DATA_HOST_TRAFFIC:
1331
case SORT_DATA_THPT:
1332
sentPercent = rcvdPercent = 0;
1336
/* Fixed buffer overflow.
1337
Courtesy of Rainer Tammer <rainer.tammer@spg.schulergroup.com>
1340
strncpy(webHostName, makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 1,
1341
hostLinkBuf, sizeof(hostLinkBuf)),
1342
sizeof(webHostName));
1344
switch(reportType) {
1345
case SORT_DATA_RECEIVED_PROTOS:
1346
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1347
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
1348
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1349
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>""<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1350
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1351
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1352
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1353
getRowColor(), webHostName,
1354
formatBytes(el->bytesRcvd.value, 1, formatBuf, sizeof(formatBuf)),
1355
rcvdPercent, myGlobals.separator,
1356
formatBytes(el->tcpRcvdLoc.value+el->tcpRcvdFromRem.value, 1, formatBuf1, sizeof(formatBuf1)),
1357
formatBytes(el->udpRcvdLoc.value+el->udpRcvdFromRem.value, 1, formatBuf2, sizeof(formatBuf2)),
1358
formatBytes(el->icmpRcvd.value, 1, formatBuf3, sizeof(formatBuf3)),
1359
formatBytes(el->icmp6Rcvd.value, 1, formatBuf4, sizeof(formatBuf4)),
1360
formatBytes(el->dlcRcvd.value, 1, formatBuf5, sizeof(formatBuf5)),
1361
formatBytes(el->ipxRcvd.value, 1, formatBuf6, sizeof(formatBuf6)),
1362
formatBytes(el->decnetRcvd.value, 1, formatBuf7, sizeof(formatBuf7)),
1363
formatBytes(el->arp_rarpRcvd.value, 1, formatBuf8, sizeof(formatBuf8)),
1364
formatBytes(el->appletalkRcvd.value, 1, formatBuf9, sizeof(formatBuf9))
1365
) < 0) BufferTooShort();
1368
if(snprintf(buf, sizeof(buf),
1369
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1370
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1371
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1372
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1373
formatBytes(el->netbiosRcvd.value, 1, formatBuf1, sizeof(formatBuf1)),
1374
formatBytes(el->osiRcvd.value, 1, formatBuf2, sizeof(formatBuf2)),
1375
formatBytes(el->ipv6Rcvd.value, 1, formatBuf3, sizeof(formatBuf3)),
1376
formatBytes(el->stpRcvd.value, 1, formatBuf4, sizeof(formatBuf4))) < 0) BufferTooShort();
1379
protoList = myGlobals.ipProtosList, idx1=0;
1380
while(protoList != NULL) {
1381
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1382
formatBytes(el->ipProtosList[idx1].rcvd.value, 1,
1383
formatBuf, sizeof(formatBuf))) < 0) BufferTooShort();
1386
idx1++, protoList = protoList->next;
1389
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1390
formatBytes(el->otherRcvd.value, 1, formatBuf, sizeof(formatBuf))) < 0) BufferTooShort();
1393
case SORT_DATA_SENT_PROTOS:
1394
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1395
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
1396
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1397
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1398
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1399
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>""<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1400
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1401
getRowColor(), webHostName,
1402
formatBytes(el->bytesSent.value, 1, formatBuf, sizeof(formatBuf)), sentPercent, myGlobals.separator,
1403
formatBytes(el->tcpSentLoc.value+el->tcpSentRem.value, 1, formatBuf1, sizeof(formatBuf1)),
1404
formatBytes(el->udpSentLoc.value+el->udpSentRem.value, 1, formatBuf2, sizeof(formatBuf2)),
1405
formatBytes(el->icmpSent.value, 1, formatBuf3, sizeof(formatBuf3)),
1406
formatBytes(el->icmp6Sent.value, 1, formatBuf4, sizeof(formatBuf4)),
1407
formatBytes(el->dlcSent.value, 1, formatBuf5, sizeof(formatBuf5)),
1408
formatBytes(el->ipxSent.value, 1, formatBuf6, sizeof(formatBuf6)),
1409
formatBytes(el->decnetSent.value, 1, formatBuf7, sizeof(formatBuf7)),
1410
formatBytes(el->arp_rarpSent.value, 1, formatBuf8, sizeof(formatBuf8)),
1411
formatBytes(el->appletalkSent.value, 1, formatBuf9, sizeof(formatBuf9))
1412
) < 0) BufferTooShort();
1416
if(snprintf(buf, sizeof(buf),
1417
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1418
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1419
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1420
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1421
formatBytes(el->netbiosSent.value, 1, formatBuf, sizeof(formatBuf)),
1422
formatBytes(el->osiSent.value, 1, formatBuf1, sizeof(formatBuf1)),
1423
formatBytes(el->ipv6Sent.value, 1, formatBuf2, sizeof(formatBuf2)),
1424
formatBytes(el->stpSent.value, 1, formatBuf3, sizeof(formatBuf3))) < 0) BufferTooShort();
1427
protoList = myGlobals.ipProtosList, idx1=0;
1428
while(protoList != NULL) {
1429
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1430
formatBytes(el->ipProtosList[idx1].sent.value, 1,
1431
formatBuf, sizeof(formatBuf))) < 0) BufferTooShort();
1434
idx1++, protoList = protoList->next;
1437
if(snprintf(buf, sizeof(buf),
1438
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1439
formatBytes(el->otherSent.value, 1, formatBuf, sizeof(formatBuf))
1440
) < 0) BufferTooShort();
1443
case SORT_DATA_PROTOS:
1444
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1445
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
1446
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1447
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1448
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1449
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>""<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1450
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1451
getRowColor(), webHostName,
1452
formatBytes(el->bytesSent.value+el->bytesRcvd.value, 1, formatBuf, sizeof(formatBuf)),
1453
totPercent, myGlobals.separator,
1454
formatBytes(el->tcpSentLoc.value+el->tcpSentRem.value+
1455
el->tcpRcvdLoc.value+el->tcpRcvdFromRem.value, 1, formatBuf1, sizeof(formatBuf1)),
1456
formatBytes(el->udpSentLoc.value+el->udpSentRem.value+
1457
el->udpRcvdLoc.value+el->udpRcvdFromRem.value, 1, formatBuf2, sizeof(formatBuf2)),
1458
formatBytes(el->icmpSent.value+el->icmpRcvd.value, 1, formatBuf3, sizeof(formatBuf3)),
1459
formatBytes(el->icmp6Sent.value+el->icmp6Rcvd.value, 1, formatBuf4, sizeof(formatBuf4)),
1460
formatBytes(el->dlcSent.value+el->dlcRcvd.value, 1, formatBuf5, sizeof(formatBuf5)),
1461
formatBytes(el->ipxSent.value+el->ipxRcvd.value, 1, formatBuf6, sizeof(formatBuf6)),
1462
formatBytes(el->decnetSent.value+el->decnetRcvd.value, 1, formatBuf7, sizeof(formatBuf7)),
1463
formatBytes(el->arp_rarpSent.value+el->arp_rarpRcvd.value, 1, formatBuf8, sizeof(formatBuf8)),
1464
formatBytes(el->appletalkSent.value+el->appletalkRcvd.value, 1, formatBuf9, sizeof(formatBuf9))
1465
) < 0) BufferTooShort();
1469
if(snprintf(buf, sizeof(buf),
1470
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1471
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1472
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1473
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1474
formatBytes(el->netbiosSent.value+el->netbiosRcvd.value, 1, formatBuf, sizeof(formatBuf)),
1475
formatBytes(el->osiSent.value+el->osiRcvd.value, 1, formatBuf1, sizeof(formatBuf1)),
1476
formatBytes(el->ipv6Sent.value+el->ipv6Rcvd.value, 1, formatBuf2, sizeof(formatBuf2)),
1477
formatBytes(el->stpSent.value+el->stpRcvd.value, 1, formatBuf3, sizeof(formatBuf3))) < 0) BufferTooShort();
1480
protoList = myGlobals.ipProtosList, idx1=0;
1481
while(protoList != NULL) {
1482
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1483
formatBytes(el->ipProtosList[idx1].sent.value
1484
+el->ipProtosList[idx1].rcvd.value, 1, formatBuf, sizeof(formatBuf))) < 0) BufferTooShort();
1487
idx1++, protoList = protoList->next;
1490
if(snprintf(buf, sizeof(buf),
1491
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1492
formatBytes(el->otherSent.value+el->otherRcvd.value, 1, formatBuf, sizeof(formatBuf))
1493
) < 0) BufferTooShort();
1497
case SORT_DATA_RECEIVED_IP:
1499
Counter totalIPTraffic=0;
1501
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1502
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>",
1503
getRowColor(), webHostName,
1504
formatBytes(el->ipBytesRcvd.value, 1, formatBuf, sizeof(formatBuf)),
1505
rcvdPercent, myGlobals.separator) < 0)
1509
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
1510
totalIPTraffic += el->protoIPTrafficInfos[i].rcvdLoc.value+
1511
el->protoIPTrafficInfos[i].rcvdFromRem.value;
1512
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1513
formatBytes(el->protoIPTrafficInfos[i].rcvdLoc.value+
1514
el->protoIPTrafficInfos[i].rcvdFromRem.value, 1,
1515
formatBuf, sizeof(formatBuf))) < 0)
1520
/* Rounding may cause troubles */
1521
if(el->ipBytesRcvd.value > totalIPTraffic)
1522
totalIPTraffic = el->ipBytesRcvd.value - totalIPTraffic;
1525
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1526
formatBytes(totalIPTraffic, 1, formatBuf, sizeof(formatBuf))) < 0)
1531
case SORT_DATA_SENT_IP:
1533
Counter totalIPTraffic=0;
1535
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1536
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>",
1537
getRowColor(), webHostName,
1538
formatBytes(el->ipBytesSent.value, 1, formatBuf, sizeof(formatBuf)),
1539
sentPercent, myGlobals.separator) < 0)
1543
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
1544
totalIPTraffic += el->protoIPTrafficInfos[i].sentLoc.value+
1545
el->protoIPTrafficInfos[i].sentRem.value;
1546
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1547
formatBytes(el->protoIPTrafficInfos[i].sentLoc.value+
1548
el->protoIPTrafficInfos[i].sentRem.value, 1,
1549
formatBuf, sizeof(formatBuf))) < 0)
1554
/* Rounding may cause troubles */
1555
if(el->ipBytesSent.value > totalIPTraffic)
1556
totalIPTraffic = el->ipBytesSent.value - totalIPTraffic;
1559
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1560
formatBytes(totalIPTraffic, 1, formatBuf, sizeof(formatBuf))) < 0)
1567
Counter totalIPTraffic=0;
1569
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1570
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>",
1571
getRowColor(), webHostName,
1572
formatBytes(el->ipBytesSent.value+el->ipBytesRcvd.value, 1, formatBuf, sizeof(formatBuf)),
1573
totPercent, myGlobals.separator) < 0)
1577
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
1578
totalIPTraffic += el->protoIPTrafficInfos[i].sentLoc.value+
1579
el->protoIPTrafficInfos[i].rcvdLoc.value+
1580
el->protoIPTrafficInfos[i].sentRem.value+
1581
el->protoIPTrafficInfos[i].rcvdFromRem.value;
1582
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1583
formatBytes(el->protoIPTrafficInfos[i].sentLoc.value+
1584
el->protoIPTrafficInfos[i].rcvdLoc.value+
1585
el->protoIPTrafficInfos[i].sentRem.value+
1586
el->protoIPTrafficInfos[i].rcvdFromRem.value, 1,
1587
formatBuf, sizeof(formatBuf))) < 0)
1592
/* Rounding may cause troubles */
1593
if(el->ipBytesSent.value+el->ipBytesRcvd.value > totalIPTraffic)
1594
totalIPTraffic = el->ipBytesSent.value + el->ipBytesRcvd.value - totalIPTraffic;
1597
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
1598
formatBytes(totalIPTraffic, 1, formatBuf, sizeof(formatBuf))) < 0)
1603
case SORT_DATA_RECEIVED_THPT:
1605
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1606
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1607
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1608
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1609
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
1610
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
1611
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>",
1612
getRowColor(), webHostName,
1613
formatThroughput(el->actualRcvdThpt, 1, formatBuf, sizeof(formatBuf)),
1614
formatThroughput(el->averageRcvdThpt, 1, formatBuf1, sizeof(formatBuf1)),
1615
formatThroughput(el->peakRcvdThpt, 1, formatBuf2, sizeof(formatBuf2)),
1616
el->actualRcvdPktThpt,
1617
el->averageRcvdPktThpt,
1618
el->peakRcvdPktThpt, 1) < 0)
1623
case SORT_DATA_SENT_THPT:
1625
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1626
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1627
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1628
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1629
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
1630
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
1631
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>",
1632
getRowColor(), webHostName,
1633
formatThroughput(el->actualSentThpt, 1, formatBuf, sizeof(formatBuf)),
1634
formatThroughput(el->averageSentThpt, 1, formatBuf1, sizeof(formatBuf1)),
1635
formatThroughput(el->peakSentThpt, 1, formatBuf2, sizeof(formatBuf2)),
1636
el->actualSentPktThpt,
1637
el->averageSentPktThpt,
1638
el->peakSentPktThpt) < 0)
1643
case SORT_DATA_THPT:
1645
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1646
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1647
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1648
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1649
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
1650
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
1651
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>",
1652
getRowColor(), webHostName,
1653
formatThroughput(el->actualTThpt, 1, formatBuf, sizeof(formatBuf)),
1654
formatThroughput(el->averageTThpt, 1, formatBuf1, sizeof(formatBuf1)),
1655
formatThroughput(el->peakTThpt, 1, formatBuf2, sizeof(formatBuf2)),
1657
el->averageTPktThpt,
1658
el->peakTPktThpt) < 0)
1663
case SORT_DATA_RCVD_HOST_TRAFFIC:
1664
case SORT_DATA_SENT_HOST_TRAFFIC:
1665
case SORT_DATA_HOST_TRAFFIC:
1668
if(snprintf(buf, sizeof(buf), "<TR %s>%s", getRowColor(), webHostName) < 0)
1671
printHostThtpShort(el, reportType, hourId);
1676
sendString("</TR>\n");
1678
/* Avoid huge tables */
1679
if(printedEntries++ > myGlobals.maxNumLines)
1686
sendString("\n</TABLE>"TABLE_OFF"\n");
1688
switch(reportType) {
1689
case SORT_DATA_RCVD_HOST_TRAFFIC:
1690
case SORT_DATA_SENT_HOST_TRAFFIC:
1691
case SORT_DATA_HOST_TRAFFIC:
1692
case SORT_DATA_RECEIVED_THPT:
1693
case SORT_DATA_SENT_THPT:
1694
case SORT_DATA_THPT:
1696
case SORT_DATA_RECEIVED_PROTOS:
1697
case SORT_DATA_RECEIVED_IP:
1698
case SORT_DATA_SENT_PROTOS:
1699
case SORT_DATA_SENT_IP:
1700
case SORT_DATA_PROTOS:
1702
sendString("<P><I>Note: These counters do not include broadcasts and will not equal the 'Global Protocol Distribution'</I></P>\n");
1706
sendString("</CENTER>\n");
1708
printFooter(reportType);
1710
addPageIndicator(url, pageNum, numEntries, myGlobals.maxNumLines,
1711
revertOrder, abs(sortedColumn));
1713
sendString("<p><b>NOTE</b>:</p>\n<ul>"
1714
"<li>Click <a href=\"" CONST_HOST_SORT_NOTE_HTML "\">here</a> "
1715
"for more information about host and domain sorting.</li>\n"
1718
myGlobals.lastRefreshTime = myGlobals.actTime;
1722
/* ******************************* */
1724
void printMulticastStats(int sortedColumn /* ignored so far */,
1727
u_int idx, numEntries=0, maxHosts;
1728
int printedEntries=0, i;
1730
HostTraffic** tmpTable;
1731
char buf[LEN_GENERAL_WORK_BUFFER], *sign, *theAnchor[6], *arrow[6], *arrowGif;
1732
char formatBuf[32], formatBuf1[32], formatBuf2[32], formatBuf3[32];
1733
char htmlAnchor[64], htmlAnchor1[64], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
1735
printHTMLheader("Multicast Statistics", NULL, 0);
1737
memset(buf, 0, sizeof(buf));
1738
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
1740
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "printMulticastStats");
1741
if(tmpTable == NULL)
1744
/* All the ALT tags courtesy of "Burton M. Strauss III" <BStrauss3@attbi.com> */
1747
arrowGif = " " CONST_IMG_ARROW_UP;
1750
arrowGif = " " CONST_IMG_ARROW_DOWN;
1753
for(el=getFirstHost(myGlobals.actualReportDeviceId);
1754
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
1755
if(((el->pktMulticastSent.value > 0) || (el->pktMulticastRcvd.value > 0))
1756
&& (!broadcastHost(el)))
1757
tmpTable[numEntries++] = el;
1759
if(numEntries >= maxHosts)
1763
if(numEntries > 0) {
1764
myGlobals.columnSort = sortedColumn; /* Host name */
1766
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", CONST_MULTICAST_STATS_HTML, sign) < 0)
1768
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", CONST_MULTICAST_STATS_HTML) < 0)
1772
if(abs(myGlobals.columnSort) == i)
1773
arrow[i] = arrowGif, theAnchor[i] = htmlAnchor;
1775
arrow[i] = "", theAnchor[i] = htmlAnchor1;
1777
sendString("<CENTER>\n");
1778
if(snprintf(buf, sizeof(buf), ""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON" "DARK_BG"><TH "TH_BG">%s0>Host%s</A></TH>\n"
1779
"<TH "TH_BG">%s1>Domain%s</A></TH>"
1780
"<TH "TH_BG">%s2>Pkts Sent%s</A></TH>"
1781
"<TH "TH_BG">%s3>Data Sent%s</A></TH>"
1782
"<TH "TH_BG">%s4>Pkts Rcvd%s</A></TH>"
1783
"<TH "TH_BG">%s5>Data Rcvd%s</A></TH>"
1785
theAnchor[0], arrow[0],
1786
theAnchor[1], arrow[1],
1787
theAnchor[2], arrow[2],
1788
theAnchor[3], arrow[3],
1789
theAnchor[4], arrow[4],
1790
theAnchor[5], arrow[5]
1791
) < 0) BufferTooShort();
1794
qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpMulticastFctn);
1796
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
1798
el = tmpTable[numEntries-idx-1];
1803
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>%s"
1804
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1805
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
1807
getRowColor(), makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 1, hostLinkBuf, sizeof(hostLinkBuf)),
1808
formatPkts(el->pktMulticastSent.value, formatBuf, sizeof(formatBuf)),
1809
formatBytes(el->bytesMulticastSent.value, 1, formatBuf1, sizeof(formatBuf1)),
1810
formatPkts(el->pktMulticastRcvd.value, formatBuf2, sizeof(formatBuf2)),
1811
formatBytes(el->bytesMulticastRcvd.value, 1, formatBuf3, sizeof(formatBuf3))) < 0) BufferTooShort();
1815
/* Avoid huge tables */
1816
if(printedEntries++ > myGlobals.maxNumLines)
1821
sendString("</TABLE>"TABLE_OFF"\n");
1822
sendString("</CENTER>\n");
1824
addPageIndicator(CONST_MULTICAST_STATS_HTML, pageNum, numEntries, myGlobals.maxNumLines,
1825
revertOrder, abs(sortedColumn));
1827
printFooterHostLink();
1835
/* ******************************* */
1837
void printHostsInfo(int sortedColumn, int revertOrder, int pageNum) {
1838
u_int idx, numEntries=0, maxHosts;
1839
int printedEntries=0;
1840
unsigned short maxBandwidthUsage=1 /* avoid divisions by zero */;
1842
HostTraffic** tmpTable;
1843
char buf[2*LEN_GENERAL_WORK_BUFFER], *arrowGif, *sign, *arrow[11], *theAnchor[11], osBuf[128];
1844
char htmlAnchor[64], htmlAnchor1[64];
1845
char formatBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
1847
printHTMLheader("Host Information", NULL, 0);
1849
memset(buf, 0, sizeof(buf));
1850
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
1852
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "printHostsInfo");
1853
if(tmpTable == NULL)
1858
arrowGif = " " CONST_IMG_ARROW_UP;
1861
arrowGif = " " CONST_IMG_ARROW_DOWN;
1864
myGlobals.columnSort = sortedColumn;
1866
for(el=getFirstHost(myGlobals.actualReportDeviceId);
1867
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
1868
unsigned short actUsage, actUsageS, actUsageR;
1870
if(isFcHost (el) || broadcastHost(el)) continue;
1872
actUsage = (unsigned short)(0.5+100.0*(((float)el->bytesSent.value+(float)el->bytesRcvd.value)/
1873
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
1874
actUsageS = (unsigned short)(0.5+100.0*((float)el->bytesSent.value/
1875
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
1876
actUsageR = (unsigned short)(0.5+100.0*((float)el->bytesRcvd.value/
1877
(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
1879
el->actBandwidthUsage = actUsage;
1880
if(el->actBandwidthUsage > maxBandwidthUsage)
1881
maxBandwidthUsage = actUsage;
1882
el->actBandwidthUsageS = actUsageS;
1883
el->actBandwidthUsageR = actUsageR;
1885
tmpTable[numEntries++] = el;
1888
if(numEntries >= maxHosts)
1892
if(numEntries > 0) {
1895
qsort(tmpTable, numEntries, sizeof(HostTraffic*), sortHostFctn);
1897
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=\"/%s?col=%s", CONST_HOSTS_INFO_HTML, sign) < 0)
1899
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=\"/%s?col=", CONST_HOSTS_INFO_HTML) < 0)
1902
for(i=1; i<=10; i++) {
1903
if(abs(myGlobals.columnSort) == i) {
1904
arrow[i] = arrowGif;
1905
theAnchor[i] = htmlAnchor;
1908
theAnchor[i] = htmlAnchor1;
1912
if(abs(myGlobals.columnSort) == FLAG_DOMAIN_DUMMY_IDX) {
1913
arrow[0] = arrowGif;
1914
theAnchor[0] = htmlAnchor;
1917
theAnchor[0] = htmlAnchor1;
1920
if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
1921
if(snprintf(buf, sizeof(buf), "<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON" "DARK_BG">"
1922
"<TH "TH_BG">%s1\">Host%s</A></TH>\n"
1923
"<TH "TH_BG">%s"FLAG_DOMAIN_DUMMY_IDX_STR"\">Domain%s</A></TH>\n"
1924
"<TH "TH_BG">%s2\">IP Address%s</A></TH>\n"
1925
"<TH "TH_BG">%s3\">MAC Address%s</A></TH>\n"
1926
"<TH "TH_BG">%s6\">Other Name(s)%s</A></TH>\n"
1927
"<TH "TH_BG">%s4\">Bandwidth%s</A></TH>\n"
1928
"<TH "TH_BG">%s5\">Nw Board Vendor%s</A></TH>\n"
1929
"<TH "TH_BG">%s7\">Hops Distance%s</A></TH>\n"
1930
"<TH "TH_BG">%s8\">Host Contacts%s</A></TH>\n"
1931
"<TH "TH_BG">%s9\">Age%s</A></TH>\n"
1932
"<TH "TH_BG">%s10\">AS%s</A></TH>"
1934
theAnchor[1], arrow[1],
1935
theAnchor[0], arrow[0],
1936
theAnchor[2], arrow[2],
1937
theAnchor[3], arrow[3],
1938
theAnchor[6], arrow[6],
1939
theAnchor[4], arrow[4],
1940
theAnchor[5], arrow[5],
1941
theAnchor[7], arrow[7],
1942
theAnchor[8], arrow[8],
1943
theAnchor[9], arrow[9],
1944
theAnchor[10], arrow[10]
1948
if(snprintf(buf, sizeof(buf), "<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON" "DARK_BG">"
1949
"<TH "TH_BG">%s1\">Host%s</A></TH>\n"
1950
"<TH "TH_BG">%s"FLAG_DOMAIN_DUMMY_IDX_STR"\">Domain%s</A></TH>\n"
1951
"</TH><TH "TH_BG">%s2\">IP Address%s</A></TH>\n"
1952
"<TH "TH_BG">%s6\">Other Name(s)%s</A></TH>\n"
1953
"<TH "TH_BG">%s4\">Bandwidth%s</A></TH>\n"
1954
"<TH "TH_BG">%s7\">Hops Distance%s</A></TH>\n"
1955
"<TH "TH_BG">%s8\">Host Contacts%s</A></TH>\n"
1956
"<TH "TH_BG">%s9\">Age%s</A></TH>\n"
1957
"<TH "TH_BG">%s10\">AS%s</A></TH>"
1959
theAnchor[1], arrow[1],
1960
theAnchor[0], arrow[0],
1961
theAnchor[2], arrow[2],
1962
theAnchor[6], arrow[6],
1963
theAnchor[4], arrow[4],
1964
theAnchor[7], arrow[7],
1965
theAnchor[8], arrow[8],
1966
theAnchor[9], arrow[9],
1967
theAnchor[10], arrow[10]
1973
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
1975
el = tmpTable[numEntries-idx-1];
1980
char *tmpName1, *tmpName2, *tmpName3, sniffedName[MAXDNAME];
1981
int displaySniffedName=0;
1983
tmpName1 = el->hostNumIpAddress;
1985
if((tmpName1[0] == '\0') || (strcmp(tmpName1, "0.0.0.0") == 0))
1986
tmpName1 = myGlobals.separator;
1988
if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
1989
tmpName2 = getVendorInfo(el->ethAddress, 1);
1990
if(tmpName2[0] == '\0')
1991
tmpName2 = myGlobals.separator;
1993
tmpName3 = el->ethAddressString;
1994
if((tmpName3[0] == '\0')
1995
|| (strcmp(tmpName3, "00:00:00:00:00:00") == 0))
1996
tmpName3 = myGlobals.separator;
1998
tmpName2 = myGlobals.separator;
1999
tmpName3 = myGlobals.separator;
2002
if(!addrnull(&el->hostIpAddress)
2003
&& (getSniffedDNSName(el->hostNumIpAddress,
2004
sniffedName, sizeof(sniffedName)))) {
2006
traceEvent(CONST_TRACE_INFO, "%s <=> %s [%s/%s]",
2007
el->hostNumIpAddress, sniffedName,
2008
el->hostResolvedName, el->hostNumIpAddress);
2011
if((el->hostResolvedName[0] == '\0') || strcmp(sniffedName, el->hostResolvedName)) {
2012
if((el->hostResolvedName[0] == '\0')
2013
|| (strcmp(el->hostResolvedName, el->hostNumIpAddress) == 0)) {
2014
if(strlen(sniffedName) >= (MAX_LEN_SYM_HOST_NAME-1))
2015
sniffedName[MAX_LEN_SYM_HOST_NAME-2] = '\0';
2017
for(i=0; i<strlen(sniffedName); i++) if(isupper(sniffedName[i])) tolower(sniffedName[i]);
2018
setResolvedName(el, sniffedName, FLAG_HOST_SYM_ADDR_TYPE_NAME);
2020
displaySniffedName=1;
2024
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>", getRowColor()) < 0)
2028
sendString(makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 1, hostLinkBuf, sizeof(hostLinkBuf)));
2030
if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
2031
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
2032
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
2033
tmpName1, tmpName3) < 0)
2036
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
2042
sendString("<TD "TD_BG" ALIGN=RIGHT NOWRAP>");
2044
if(el->nonIPTraffic && displaySniffedName) {
2045
short numAddresses = 0;
2047
if(el->nonIPTraffic->nbHostName && el->nonIPTraffic->nbDomainName) {
2048
if((el->nonIPTraffic->nbAccountName != NULL) && ((el->nonIPTraffic->nbAccountName[0] != '0'))) {
2049
if((el->nonIPTraffic->nbDomainName != NULL) && (el->nonIPTraffic->nbDomainName[0] != '0')) {
2050
if(snprintf(buf, sizeof(buf), "%s %s@%s [%s]", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
2051
el->nonIPTraffic->nbAccountName, el->nonIPTraffic->nbHostName,
2052
el->nonIPTraffic->nbDomainName) < 0)
2055
if(snprintf(buf, sizeof(buf), "%s %s@%s", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
2056
el->nonIPTraffic->nbAccountName, el->nonIPTraffic->nbHostName) < 0)
2060
if((el->nonIPTraffic->nbDomainName != NULL) && (el->nonIPTraffic->nbDomainName[0] != '0')) {
2061
if(snprintf(buf, sizeof(buf), "%s %s [%s]", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
2062
el->nonIPTraffic->nbHostName, el->nonIPTraffic->nbDomainName) < 0)
2065
if(snprintf(buf, sizeof(buf), "%s %s", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
2066
el->nonIPTraffic->nbHostName) < 0)
2072
} else if(el->nonIPTraffic->nbHostName) {
2073
if(snprintf(buf, sizeof(buf), "%s %s", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
2074
el->nonIPTraffic->nbHostName) < 0) BufferTooShort();
2079
if(el->nonIPTraffic->nbDescr) {
2080
if(snprintf(buf, sizeof(buf), ": %s", el->nonIPTraffic->nbDescr) < 0)
2085
if (displaySniffedName) {
2086
if(numAddresses > 0) sendString("/");
2087
if(snprintf(buf, sizeof(buf), "%s", sniffedName) < 0)
2093
if(el->nonIPTraffic->atNetwork) {
2094
char *nodeName = el->nonIPTraffic->atNodeName;
2096
if(numAddresses > 0) sendString("/");
2097
if(nodeName == NULL) nodeName = "";
2099
if(snprintf(buf, sizeof(buf), "%s %s ",
2100
getOSFlag(el, "Mac", 0, osBuf, sizeof(osBuf)), nodeName) < 0)
2104
if(el->nonIPTraffic->atNodeType[0] != NULL) {
2106
for(i=0; i<MAX_NODE_TYPES; i++)
2107
if(el->nonIPTraffic->atNodeType[i] == NULL)
2110
if(i > 0) sendString("/");
2111
sendString(el->nonIPTraffic->atNodeType[i]);
2114
sendString(") ");
2117
if(snprintf(buf, sizeof(buf), "[%d.%d]",
2118
el->nonIPTraffic->atNetwork, el->nonIPTraffic->atNode) < 0)
2124
if(el->nonIPTraffic->ipxHostName) {
2127
if(numAddresses > 0) sendString("/");
2128
if(snprintf(buf, sizeof(buf), "%s %s ",
2129
getOSFlag(el, "Novell", 0, osBuf, sizeof(osBuf)),
2130
el->nonIPTraffic->ipxHostName) < 0)
2134
for(i=0; i<el->nonIPTraffic->numIpxNodeTypes; i++) {
2135
char *str = getSAPInfo(el->nonIPTraffic->ipxNodeType[i], 1);
2137
if(str[0] != '\0') {
2148
if(numSap > 0) sendString("]");
2154
sendString(" </TD>");
2155
printBar(buf, sizeof(buf), el->actBandwidthUsageS, el->actBandwidthUsageR, maxBandwidthUsage, 3);
2157
if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
2158
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>", tmpName2) < 0)
2166
if(!subnetPseudoLocalHost(el)) {
2171
sprintf(shortBuf, "%d", i % 256);
2173
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT> %s</TD>",
2174
(i == 0) ? "" : shortBuf) < 0)
2179
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%lu</TD>",
2180
(unsigned long)(el->totContactedSentPeers+el->totContactedRcvdPeers)) < 0)
2186
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s-",
2187
formatLatency(el->minLatency, FLAG_STATE_ACTIVE)) < 0)
2191
if(snprintf(buf, sizeof(buf), "%s</TD>",
2192
formatLatency(el->maxLatency, FLAG_STATE_ACTIVE)) < 0)
2197
if(snprintf(buf, sizeof(buf), "<td "TD_BG" align=\"right\" nowrap>%s</td>",
2198
formatSeconds(el->lastSeen - el->firstSeen, formatBuf, sizeof(formatBuf))) < 0)
2202
if(el->hostAS == 0) {
2203
sendString("<TD "TD_BG" ALIGN=RIGHT NOWRAP> </TD>");
2205
if(snprintf(buf, sizeof(buf),
2206
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>"
2207
"<a href=\"" DEFAULT_AS_LOOKUP_URL "%d\" title=\"Lookup ASN (offsite)\">%d</a>"
2209
el->hostAS, el->hostAS) < 0)
2214
sendString("</TR>\n");
2218
/* Avoid huge tables */
2219
if(printedEntries > myGlobals.maxNumLines)
2222
traceEvent(CONST_TRACE_WARNING, "qsort() problem!");
2226
sendString("</TABLE>"TABLE_OFF"<P>\n");
2227
sendString("</CENTER>\n");
2229
printFooterHostLink();
2231
printBandwidthFooter();
2233
addPageIndicator(CONST_HOSTS_INFO_HTML, pageNum, numEntries, myGlobals.maxNumLines,
2234
revertOrder, abs(sortedColumn));
2240
/* ************************************ */
2242
void printAllSessionsHTML (char* host, int actualDeviceId, int sortedColumn,
2243
int revertOrder, int pageNum, char *url,
2246
HostTraffic *el=NULL;
2247
char buf[LEN_GENERAL_WORK_BUFFER];
2248
char formatBuf[32], portBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
2254
if ((tok = strchr (host, '-')) != NULL) {
2255
vsanId = atoi (&tok[1]);
2259
for(el=getFirstHost(actualDeviceId);
2260
el != NULL; el = getNextHost(actualDeviceId, el)) {
2261
if((strcmp(el->hostNumIpAddress, host) == 0)
2262
|| (strcmp(el->ethAddressString, host) == 0)) {
2266
else if ((strncmp (fc_to_str ((u_int8_t *)&el->hostFcAddress),
2267
host, LEN_FC_ADDRESS_DISPLAY) == 0) &&
2268
((el->vsanId == vsanId) || (vsanId == 0))) {
2274
/* Dennis Schoen (dennis@cns.dnsalias.org)
2276
* send 404 if we cannot generate the requested page
2278
if((el == NULL) || (!found)) {
2279
char errorAdditionalText[512];
2280
if(snprintf(errorAdditionalText, sizeof(errorAdditionalText),
2281
"<p align=\"center\"><img alt=\"Warning\" src=\"/warning.gif\"></p>\n"
2282
"<p align=\"center\"><font color=\"#FF0000\" size=\"+1\">"
2283
"<b>ntop</b> does not currently have any information about host %s.</font></p>"
2285
"<p>This is most likely because the host information has been "
2286
"purged as inactive. You may wish to consider the -c | --sticky-hosts "
2287
"option, although that option may substantially increase memory "
2288
"requirements.</p>\n",
2291
returnHTTPpageNotFound(errorAdditionalText);
2294
sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1);
2296
/* ************************************ */
2298
if (found && !foundFcHost) {
2299
printHostDetailedInfo(el, actualDeviceId);
2300
printHostTrafficStats(el, actualDeviceId);
2301
printHostIcmpStats(el);
2302
printHostFragmentStats(el, actualDeviceId);
2303
printHostContactedPeers(el, actualDeviceId);
2304
printHostHTTPVirtualHosts(el, actualDeviceId);
2305
printHostUsedServices(el, actualDeviceId);
2307
else if (foundFcHost) {
2308
printFcHostHeader (el, url, revertOrder, sortedColumn, hostInfoPage);
2309
switch (hostInfoPage) {
2310
case showHostMainPage:
2311
printFcHostDetailedInfo (el, actualDeviceId);
2312
printFcHostTrafficStats (el, actualDeviceId);
2313
printFcHostContactedPeers(el, actualDeviceId);
2315
case showHostLunStats:
2316
if (el->devType != SCSI_DEV_INITIATOR) {
2317
printScsiLunStats (el, actualDeviceId, sortedColumn,
2318
revertOrder, pageNum, url);
2321
case showHostLunGraphs:
2322
if (el->devType != SCSI_DEV_INITIATOR) {
2323
printScsiLunGraphs (el, actualDeviceId);
2326
case showHostScsiSessionBytes:
2327
printScsiSessionBytes (actualDeviceId, sortedColumn, revertOrder,
2330
case showHostScsiSessionTimes:
2331
printScsiSessionTimes (actualDeviceId, sortedColumn, revertOrder,
2334
case showHostScsiSessionStatus:
2335
printScsiSessionStatusInfo (actualDeviceId, sortedColumn,
2336
revertOrder, pageNum, url, el);
2338
case showHostScsiSessionTMInfo:
2339
printScsiSessionTmInfo (actualDeviceId, sortedColumn,
2340
revertOrder, pageNum, url, el);
2342
case showHostFcSessions:
2343
printFCSessions (actualDeviceId, sortedColumn,
2344
revertOrder, pageNum, url, el);
2352
/* ***************************************************** */
2356
if(el->portsUsage != NULL) {
2357
for(idx=1; idx<MAX_ASSIGNED_IP_PORTS /* 1024 */; idx++) {
2358
if(el->portsUsage[idx] != NULL) {
2359
char *svc = getAllPortByNum(idx, portBuf, sizeof(portBuf));
2360
char webHostName[LEN_GENERAL_WORK_BUFFER];
2361
HostTraffic *peerHost;
2364
printSectionTitle("TCP/UDP Service/Port Usage\n");
2365
sendString("<CENTER>\n");
2366
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON" "DARK_BG">"
2367
"<TH "TH_BG">IP Service</TH>"
2368
"<TH "TH_BG">Port</TH>"
2369
"<TH "TH_BG"># Client Sess.</TH>"
2370
"<TH "TH_BG">Last Client Peer</TH>"
2371
"<TH "TH_BG"># Server Sess.</TH>"
2372
"<TH "TH_BG">Last Server Peer</TH>"
2378
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT "DARK_BG">%s</TH>"
2379
"<TD "TD_BG" ALIGN=CENTER>%d</TD>", getRowColor(), svc, idx) < 0)
2382
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT "DARK_BG">%d</TH>"
2383
"<TD "TD_BG" ALIGN=CENTER>%d</TD>", getRowColor(), idx, idx) < 0)
2389
if(el->portsUsage[idx]->clientUses > 0) {
2390
/* Fix below courtesy of Andreas Pfaller <apfaller@yahoo.com.au> */
2393
if(emptySerial(&el->portsUsage[idx]->clientUsesLastPeer))
2396
peerHost = quickHostLink(el->portsUsage[idx]->clientUsesLastPeer, actualDeviceId, &tmpEl);
2398
if(peerHost == NULL) {
2399
/* Courtesy of Roberto De Luca <deluca@tandar.cnea.gov.ar> */
2400
strncpy(webHostName, " ", sizeof(webHostName));
2402
strncpy(webHostName, makeHostLink(peerHost, FLAG_HOSTLINK_TEXT_FORMAT, 0,
2403
0, hostLinkBuf, sizeof(hostLinkBuf)),
2404
sizeof(webHostName));
2406
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%d/%s</TD>"
2407
"<TD "TD_BG" ALIGN=CENTER>%s</TD>",
2408
el->portsUsage[idx]->clientUses,
2409
formatBytes(el->portsUsage[idx]->clientTraffic.value, 1, formatBuf, sizeof(formatBuf)),
2410
webHostName) < 0) BufferTooShort();
2413
sendString("<TD "TD_BG"> </TD><TD "TD_BG"> </TD>");
2415
if(el->portsUsage[idx]->serverUses > 0) {
2418
if(emptySerial(&el->portsUsage[idx]->serverUsesLastPeer))
2421
peerHost = quickHostLink(el->portsUsage[idx]->serverUsesLastPeer, actualDeviceId, &tmpEl);
2423
if(peerHost == NULL) {
2424
/* Courtesy of Roberto De Luca <deluca@tandar.cnea.gov.ar> */
2425
strncpy(webHostName, " ", sizeof(webHostName));
2427
strncpy(webHostName, makeHostLink(peerHost, FLAG_HOSTLINK_TEXT_FORMAT, 0,
2428
0, hostLinkBuf, sizeof(hostLinkBuf)), sizeof(webHostName));
2430
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%d/%s</TD>"
2431
"<TD "TD_BG" ALIGN=CENTER>%s</TD></TR>",
2432
el->portsUsage[idx]->serverUses,
2433
formatBytes(el->portsUsage[idx]->serverTraffic.value, 1, formatBuf, sizeof(formatBuf)),
2434
webHostName) < 0) BufferTooShort();
2437
sendString("<TD "TD_BG"> </TD><TD "TD_BG"> </TD></TR>");
2443
sendString("</TABLE>"TABLE_OFF"<P>\n");
2444
sendString("</CENTER>\n");
2447
/* *********************************
2448
********************************* */
2450
if((el->otherIpPortsRcvd[MAX_NUM_RECENT_PORTS-1] >= 0) || (el->otherIpPortsSent[MAX_NUM_RECENT_PORTS-1] >= 0)) {
2451
/* We have something to show */
2454
printSectionTitle("TCP/UDP - Traffic on Other Ports\n");
2455
sendString("<CENTER>\n");
2456
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON" "DARK_BG">"
2457
"<TH "TH_BG">Client Port</TH><TH "TH_BG">Server Port</TH>"
2460
sendString("<TR "TR_ON"><TD "TD_BG" ALIGN=LEFT><UL>");
2462
for(idx=0, numPrinted=0; idx<MAX_NUM_RECENT_PORTS; idx++) {
2463
if(el->otherIpPortsSent[idx] >= 0) {
2464
if(snprintf(buf, sizeof(buf), "<LI><A HREF=\"" CONST_SHOW_PORT_TRAFFIC_HTML "?port=%d\">%s</A>\n",
2465
el->otherIpPortsSent[idx],
2466
getAllPortByNum(el->otherIpPortsSent[idx], portBuf, sizeof(portBuf))) < 0)
2473
if(numPrinted == 0) sendString(" ");
2474
sendString("</UL></TD><TD "TD_BG" ALIGN=LEFT><UL>");
2476
for(idx=0, numPrinted=0; idx<MAX_NUM_RECENT_PORTS; idx++) {
2477
if(el->otherIpPortsRcvd[idx] >= 0) {
2478
if(snprintf(buf, sizeof(buf), "<li><A HREF=\"" CONST_SHOW_PORT_TRAFFIC_HTML "?port=%d\">%s</A>\n",
2479
el->otherIpPortsRcvd[idx],
2480
getAllPortByNum(el->otherIpPortsRcvd[idx], portBuf, sizeof(portBuf))) < 0)
2487
if(numPrinted == 0) sendString(" ");
2488
sendString("</UL></TR></TABLE>"TABLE_OFF"</CENTER>");
2491
/* ****************************************************************** */
2493
if((el->recentlyUsedClientPorts[MAX_NUM_RECENT_PORTS-1] >= 0)
2494
|| (el->recentlyUsedServerPorts[MAX_NUM_RECENT_PORTS-1] >= 0)) {
2495
/* We have something to show */
2498
printSectionTitle("TCP/UDP Recently Used Ports\n");
2499
sendString("<CENTER>\n");
2500
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON" "DARK_BG">"
2501
"<TH "TH_BG">Client Port</TH><TH "TH_BG">Server Port</TH>"
2504
sendString("<TR "TR_ON"><TD "TD_BG" ALIGN=LEFT><UL>");
2506
for(idx=0, numPrinted=0; idx<MAX_NUM_RECENT_PORTS; idx++) {
2507
if(el->recentlyUsedClientPorts[idx] >= 0) {
2508
if(snprintf(buf, sizeof(buf), "<li><A HREF=\"" CONST_SHOW_PORT_TRAFFIC_HTML "?port=%d\">%s</A>\n",
2509
el->recentlyUsedClientPorts[idx],
2510
getAllPortByNum(el->recentlyUsedClientPorts[idx], portBuf, sizeof(portBuf))) < 0)
2517
if(numPrinted == 0) sendString(" ");
2519
sendString("</UL></TD><TD "TD_BG" ALIGN=LEFT><UL>");
2521
for(idx=0, numPrinted=0; idx<MAX_NUM_RECENT_PORTS; idx++) {
2522
if(el->recentlyUsedServerPorts[idx] >= 0) {
2523
if(snprintf(buf, sizeof(buf), "<LI><A HREF=\"" CONST_SHOW_PORT_TRAFFIC_HTML "?port=%d\">%s</A>\n",
2524
el->recentlyUsedServerPorts[idx],
2525
getAllPortByNum(el->recentlyUsedServerPorts[idx], portBuf, sizeof(portBuf))) < 0)
2532
if(numPrinted == 0) sendString(" ");
2533
sendString("</UL></TR></TABLE>"TABLE_OFF"</CENTER>");
2536
/* *************************************************** */
2538
if((el->protocolInfo != NULL)
2539
&& (el->protocolInfo->fileList != NULL)) {
2540
FileList *list = el->protocolInfo->fileList;
2542
printSectionTitle("P2P Recently Exchanged Files\n");
2544
sendString("<CENTER>\n");
2545
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON">"
2546
"<TH "TH_BG" NOWRAP>File Name</TH></TR>\n");
2547
sendString("<TR><TD align=left "DARK_BG"><ol>\n");
2549
while(list != NULL) {
2550
if(snprintf(buf, sizeof(buf), "<li>%s ",
2551
list->fileName) < 0)
2555
if(FD_ISSET(BITFLAG_P2P_UPLOAD_MODE, &list->fileFlags)) sendString("<IMG SRC=/upload.gif ALT=Upload VALIGN=MIDDLE> ");
2556
if(FD_ISSET(BITFLAG_P2P_DOWNLOAD_MODE, &list->fileFlags)) sendString("<IMG SRC=/download.gif ALT=Download VALIGN=MIDDLE> ");
2561
sendString("\n</ol></TD></TR></TABLE></CENTER>\n");
2564
/* *************************************************** */
2566
printHostSessions(el, actualDeviceId);
2569
/* ************************************ */
2571
void printLocalRoutersList(int actualDeviceId) {
2572
char buf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
2573
HostTraffic *el, *router;
2574
u_int i, j, numEntries=0;
2575
HostSerial routerList[MAX_NUM_ROUTERS];
2577
printHTMLheader("Local Subnet Routers", NULL, 0);
2579
if(myGlobals.dontTrustMACaddr) {
2580
printNotAvailable("-o or --no-mac");
2584
for(el=getFirstHost(actualDeviceId);
2585
el != NULL; el = getNextHost(actualDeviceId, el)) {
2586
if(subnetLocalHost(el)) {
2588
for(j=0; j<MAX_NUM_CONTACTED_PEERS; j++)
2589
if(!emptySerial(&el->contactedRouters.peersSerials[j])) {
2592
for(i=0; i<numEntries; i++) {
2593
if(cmpSerial(&el->contactedRouters.peersSerials[j], &routerList[i])) {
2599
if((found == 0) && (numEntries < MAX_NUM_ROUTERS)) {
2600
routerList[numEntries++] = el->contactedRouters.peersSerials[j];
2606
if(numEntries == 0) {
2610
sendString("<CENTER>\n");
2611
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON" "DARK_BG"><TH "TH_BG">Router Name</TH>"
2612
"<TH "TH_BG">Used by</TH></TR>\n");
2614
for(i=0; i<numEntries; i++) {
2617
if((router = quickHostLink(routerList[i], myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
2618
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left>%s</TH><TD "TD_BG" ALIGN=LEFT><UL>\n",
2620
makeHostLink(router, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
2621
hostLinkBuf, sizeof(hostLinkBuf))) < 0) BufferTooShort();
2625
for(el=getFirstHost(actualDeviceId);
2626
el != NULL; el = getNextHost(actualDeviceId, el)) {
2627
if(subnetLocalHost(el)) {
2628
for(j=0; j<MAX_NUM_CONTACTED_PEERS; j++)
2629
if(cmpSerial(&el->contactedRouters.peersSerials[j], &routerList[i])) {
2630
if(snprintf(buf, sizeof(buf), "<LI>%s</LI>\n",
2631
makeHostLink(el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
2632
hostLinkBuf, sizeof(hostLinkBuf))) < 0)
2640
sendString("</OL></TD></TR>\n");
2644
sendString("</TABLE>"TABLE_OFF"\n");
2645
sendString("</CENTER>\n");
2647
printHostColorCode(FALSE, 0);
2649
printFooterHostLink();
2653
/* ************************************ */
2655
void printIpAccounting(int remoteToLocal, int sortedColumn,
2656
int revertOrder, int pageNum) {
2657
u_int idx, numEntries=0, maxHosts;
2658
int printedEntries=0;
2659
HostTraffic *el, **tmpTable;
2660
char buf[LEN_GENERAL_WORK_BUFFER], *str=NULL, *sign, *title=NULL;
2661
Counter totalBytesSent, totalBytesRcvd, totalBytes, a=0, b=0;
2662
float sentpct, rcvdpct;
2663
time_t timeDiff = time(NULL)-myGlobals.initialSniffTime;
2664
char *arrowGif, *arrow[48], *theAnchor[48], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
2665
char htmlAnchor[64], htmlAnchor1[64];
2666
char formatBuf[32], formatBuf1[32], formatBuf2[32], formatBuf3[32];
2668
switch(remoteToLocal) {
2669
case FLAG_REMOTE_TO_LOCAL_ACCOUNTING:
2670
str = CONST_IP_R_2_L_HTML;
2671
title = "Remote to Local IP Traffic";
2673
case FLAG_REMOTE_TO_REMOTE_ACCOUNTING:
2674
str = CONST_IP_R_2_R_HTML;
2675
title = "Remote to Remote IP Traffic";
2677
case FLAG_LOCAL_TO_REMOTE_ACCOUNTING:
2678
str = CONST_IP_L_2_R_HTML;
2679
title = "Local to Remote IP Traffic";
2681
case FLAG_LOCAL_TO_LOCAL_ACCOUNTING:
2682
str = CONST_IP_L_2_L_HTML;
2683
title = "Local IP Traffic";
2687
printHTMLheader(title, NULL, 0);
2691
arrowGif = " " CONST_IMG_ARROW_UP;
2694
arrowGif = " " CONST_IMG_ARROW_DOWN;
2697
totalBytesSent=0, totalBytesRcvd=0;
2698
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
2700
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "printIpAccounting");
2701
if(tmpTable == NULL)
2704
for(el=getFirstHost(myGlobals.actualReportDeviceId);
2705
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
2706
if((broadcastHost(el) == 0) /* No broadcast addresses please */
2707
&& (multicastHost(el) == 0) /* No multicast addresses please */
2708
&& ((el->hostNumIpAddress[0] != '\0')
2709
&& (!addrnull(&el->hostIpAddress))
2710
/* This host speaks IP */)) {
2711
switch(remoteToLocal) {
2712
case FLAG_REMOTE_TO_LOCAL_ACCOUNTING:
2713
if(!subnetPseudoLocalHost(el)) {
2714
if((el->bytesSentLoc.value > 0) || (el->bytesRcvdLoc.value > 0)) {
2715
tmpTable[numEntries++]=el;
2716
totalBytesSent += el->bytesSentLoc.value;
2717
totalBytesRcvd += el->bytesRcvdLoc.value;
2721
case FLAG_REMOTE_TO_REMOTE_ACCOUNTING:
2722
if(!subnetPseudoLocalHost(el)) {
2723
if((el->bytesSentRem.value > 0) || (el->bytesRcvdFromRem.value > 0)) {
2724
tmpTable[numEntries++]=el;
2725
totalBytesSent += el->bytesSentRem.value;
2726
totalBytesRcvd += el->bytesRcvdFromRem.value;
2730
case FLAG_LOCAL_TO_REMOTE_ACCOUNTING:
2731
if(subnetPseudoLocalHost(el)) {
2732
if((el->bytesSentRem.value > 0) || (el->bytesRcvdFromRem.value > 0)) {
2733
tmpTable[numEntries++]=el;
2734
totalBytesSent += el->bytesSentRem.value;
2735
totalBytesRcvd += el->bytesRcvdFromRem.value;
2739
case FLAG_LOCAL_TO_LOCAL_ACCOUNTING:
2740
if(subnetPseudoLocalHost(el)) {
2741
if((el->bytesSentLoc.value > 0) || (el->bytesRcvdLoc.value > 0)) {
2742
tmpTable[numEntries++]=el;
2743
totalBytesSent += el->bytesSentLoc.value;
2744
totalBytesRcvd += el->bytesRcvdLoc.value;
2750
if(numEntries >= maxHosts) break;
2754
if(numEntries > 0) {
2757
myGlobals.columnSort = sortedColumn;
2758
myGlobals.sortFilter = remoteToLocal;
2759
qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpHostsFctn);
2761
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", str, sign) < 0)
2763
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", str) < 0)
2767
if(abs(myGlobals.columnSort) == i)
2768
arrow[i] = arrowGif, theAnchor[i] = htmlAnchor;
2770
arrow[i] = "", theAnchor[i] = htmlAnchor1;
2772
sendString("<CENTER>\n");
2773
if(snprintf(buf, sizeof(buf), ""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\">\n"
2774
"<TR "TR_ON" "DARK_BG"><TH "TH_BG">"
2775
"%s1>Host%s</A></TH>"
2776
"<TH "TH_BG">%s2>IP Address%s</A></TH>\n"
2777
"<TH "TH_BG" COLSPAN=2>%s3>Data Sent%s</A></TH>"
2778
"<TH "TH_BG" COLSPAN=2>%s4>Data Rcvd%s</A></TH></TR>\n",
2779
theAnchor[1], arrow[1],
2780
theAnchor[2], arrow[2], theAnchor[3], arrow[3],
2781
theAnchor[4], arrow[4]) < 0)
2786
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
2788
el = tmpTable[numEntries-idx-1];
2794
tmpName1 = el->hostNumIpAddress;
2795
if((tmpName1[0] == '\0') || (strcmp(tmpName1, "0.0.0.0") == 0))
2796
tmpName1 = myGlobals.separator;
2798
switch(remoteToLocal) {
2799
case FLAG_REMOTE_TO_LOCAL_ACCOUNTING:
2800
a = el->bytesSentLoc.value;
2801
b = el->bytesRcvdLoc.value;
2803
case FLAG_REMOTE_TO_REMOTE_ACCOUNTING:
2804
a = el->bytesSentRem.value;
2805
b = el->bytesRcvdFromRem.value;
2807
case FLAG_LOCAL_TO_REMOTE_ACCOUNTING:
2808
a = el->bytesSentRem.value;
2809
b = el->bytesRcvdFromRem.value;
2811
case FLAG_LOCAL_TO_LOCAL_ACCOUNTING:
2812
a = el->bytesSentLoc.value;
2813
b = el->bytesRcvdLoc.value;
2817
if(a < 100) /* Avoid very small decimal values */
2820
sentpct = (100*(float)a)/totalBytesSent;
2822
if(b < 100) /* Avoid very small decimal values */
2825
rcvdpct = (100*(float)b)/totalBytesRcvd;
2827
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
2828
"%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
2829
"</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
2830
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD></TR>\n",
2832
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
2834
formatBytes(a, 1, formatBuf, sizeof(formatBuf)),
2835
sentpct, myGlobals.separator,
2836
formatBytes(b, 1, formatBuf1, sizeof(formatBuf1)),
2837
rcvdpct, myGlobals.separator) < 0)
2841
/* Avoid huge tables */
2842
if(printedEntries++ > myGlobals.maxNumLines)
2847
sendString("</TABLE>"TABLE_OFF"\n");
2849
addPageIndicator(str, pageNum, numEntries, myGlobals.maxNumLines,
2850
revertOrder, abs(sortedColumn));
2852
sendString("<P>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\">\n<TR "TR_ON" "DARK_BG">"
2853
"<TH "TH_BG">Total Traffic</TH><TH "TH_BG">Data Sent</TH>\n"
2854
"<TH "TH_BG">Data Rcvd</TH><TH "TH_BG">Used Bandwidth</TH></TR>\n");
2856
totalBytes = totalBytesSent+totalBytesRcvd;
2858
/* In this case the total traffic is just half and
2859
the following statement holds:
2860
totalBytesSent == totalBytesRcvd
2862
Courtesy of Jac Engel <jacengel@home.nl>
2864
if(remoteToLocal == FLAG_LOCAL_TO_LOCAL_ACCOUNTING)
2867
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">"
2868
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
2869
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
2870
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
2871
"<TD "TD_BG" ALIGN=RIGHT>%s</TD></TR>\n",
2872
formatBytes(totalBytes, 1, formatBuf, sizeof(formatBuf)),
2873
formatBytes(totalBytesSent, 1, formatBuf1, sizeof(formatBuf1)),
2874
formatBytes(totalBytesRcvd, 1, formatBuf2, sizeof(formatBuf2)),
2875
formatThroughput((float)(totalBytes/timeDiff), 1, formatBuf3, sizeof(formatBuf3))) < 0)
2879
sendString("</TABLE>"TABLE_OFF"\n");
2880
sendString("</CENTER>\n");
2882
printFooterHostLink();
2890
/* ********************************** */
2892
void printActiveTCPSessions(int actualDeviceId, int pageNum, HostTraffic *el) {
2894
char buf[LEN_GENERAL_WORK_BUFFER], hostLinkBuf[LEN_GENERAL_WORK_BUFFER],
2895
hostLinkBuf1[LEN_GENERAL_WORK_BUFFER];
2896
int numSessions, printedSessions;
2897
char formatBuf[32], formatBuf1[32], formatBuf2[32], formatBuf3[32],
2898
formatBuf4[32], formatBuf5[32], formatBuf6[32];
2900
if(!myGlobals.enableSessionHandling) {
2901
printNotAvailable("-z or --disable-sessions");
2905
if((myGlobals.device[actualDeviceId].tcpSession == NULL) ||
2906
(myGlobals.device[actualDeviceId].numTcpSessions == 0)) {
2912
Due to the way sessions are handled, sessions before those to
2913
display need to be skipped
2916
for(idx=1, numSessions=0, printedSessions=0; idx<MAX_TOT_NUM_SESSIONS; idx++) {
2918
if(el && (printedSessions >= el->numHostSessions)) break;
2920
#ifdef CFG_MULTITHREADED
2921
accessMutex(&myGlobals.tcpSessionsMutex, "printActiveTCPSessions");
2924
if(myGlobals.device[myGlobals.actualReportDeviceId].tcpSession[idx] != NULL) {
2925
char *sport, *dport;
2926
Counter dataSent, dataRcvd;
2927
IPSession *session = myGlobals.device[myGlobals.actualReportDeviceId].tcpSession[idx];
2929
while((session != NULL) && (printedSessions < myGlobals.maxNumLines)) {
2930
#ifndef PARM_PRINT_ALL_SESSIONS
2931
if(session->sessionState != FLAG_STATE_ACTIVE) {
2932
session = session->next;
2937
if(el && (session->initiator != el) && (session->remotePeer != el)) {
2938
session = session->next;
2942
if((numSessions++) < pageNum*myGlobals.maxNumLines) {
2943
session = session->next;
2947
if(printedSessions == 0) {
2948
printHTMLheader("Active TCP Sessions", NULL, 0);
2949
sendString("<CENTER>\n");
2950
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON" "DARK_BG">"
2951
"<TH "TH_BG">Client</TH>"
2952
"<TH "TH_BG">Server</TH>"
2953
"<TH "TH_BG">Data Sent</TH>"
2954
"<TH "TH_BG">Data Rcvd</TH>"
2955
"<TH "TH_BG">Active Since</TH>"
2956
"<TH "TH_BG">Last Seen</TH>"
2957
"<TH "TH_BG">Duration</TH>"
2958
"<TH "TH_BG">Inactive</TH>"
2959
"<TH "TH_BG">Latency</TH>"
2960
#ifdef PARM_PRINT_ALL_SESSIONS
2961
"<TH "TH_BG">State</TH>"
2966
sport = getPortByNum(session->sport, IPPROTO_TCP);
2967
dport = getPortByNum(session->dport, IPPROTO_TCP);
2968
dataSent = session->bytesSent.value;
2969
dataRcvd = session->bytesRcvd.value;
2972
static char _sport[8];
2973
if(snprintf(_sport, 8, "%d", session->sport) < 0)
2979
static char _dport[8];
2980
if(snprintf(_dport, 8, "%d", session->dport) < 0)
2986
if((myGlobals.actTime < session->firstSeen)
2987
|| (session->firstSeen == 0))
2988
session->firstSeen = myGlobals.actTime;
2989
if((myGlobals.actTime < session->lastSeen)
2990
|| (session->lastSeen == 0))
2991
session->lastSeen = myGlobals.actTime;
2993
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
2994
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s:%s%s</TD>"
2995
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s:%s</TD>"
2996
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>"
2997
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>"
2998
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>"
2999
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>"
3000
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>"
3001
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>"
3002
"<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>"
3003
#ifdef PARM_PRINT_ALL_SESSIONS
3004
"<TD "TD_BG" ALIGN=CENTER>%s</TD>"
3008
makeHostLink(session->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
3010
session->isP2P == 1 ? " <P2P>" : "",
3011
makeHostLink(session->remotePeer, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof(hostLinkBuf1)),
3013
formatBytes(dataSent, 1, formatBuf, sizeof(formatBuf)),
3014
formatBytes(dataRcvd, 1, formatBuf1, sizeof(formatBuf1)),
3015
formatTime(&(session->firstSeen), formatBuf2, sizeof(formatBuf2)),
3016
formatTime(&(session->lastSeen), formatBuf3, sizeof(formatBuf3)),
3017
formatSeconds(session->lastSeen-session->firstSeen, formatBuf4, sizeof(formatBuf4)),
3018
formatSeconds(myGlobals.actTime-session->lastSeen, formatBuf5, sizeof(formatBuf5)),
3019
formatLatency(session->nwLatency, session->sessionState, formatBuf6, sizeof(formatBuf6))
3020
#ifdef PARM_PRINT_ALL_SESSIONS
3021
, getSessionState(session)
3023
) < 0) BufferTooShort();
3026
session = session->next;
3030
#ifdef CFG_MULTITHREADED
3031
releaseMutex(&myGlobals.tcpSessionsMutex);
3035
if(printedSessions > 0) {
3036
sendString("</TABLE>"TABLE_OFF"<P>\n");
3037
sendString("</CENTER>\n");
3040
addPageIndicator(CONST_ACTIVE_TCP_SESSIONS_HTML, pageNum,
3041
myGlobals.device[actualDeviceId].numTcpSessions,
3042
myGlobals.maxNumLines, -1, 0);
3044
printHostColorCode(FALSE, 0);
3046
printFooterHostLink();
3049
printHTMLheader("Active TCP Sessions", NULL, 0);
3050
printFlagedWarning("<I>No Active TCP Sessions</I>");
3056
/* ********************************** */
3058
void printIpProtocolUsage(void) {
3059
HostTraffic **hosts, *el;
3060
u_short clientPorts[MAX_ASSIGNED_IP_PORTS], serverPorts[MAX_ASSIGNED_IP_PORTS];
3061
u_int j, idx1, hostsNum=0, numPorts=0, maxHosts;
3062
char buf[LEN_GENERAL_WORK_BUFFER], portBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
3065
printHTMLheader("TCP/UDP: Local Protocol Usage", NULL, 0);
3067
memset(clientPorts, 0, sizeof(clientPorts));
3068
memset(serverPorts, 0, sizeof(serverPorts));
3070
hosts = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].hostsno*sizeof(HostTraffic*), "printIpProtocolUsage");
3074
for(el=getFirstHost(myGlobals.actualReportDeviceId);
3075
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
3076
if(subnetPseudoLocalHost(el) && (el->hostNumIpAddress[0] != '\0')) {
3077
hosts[hostsNum++] = el;
3079
if(el->portsUsage != NULL) {
3080
for(j=0; j<MAX_ASSIGNED_IP_PORTS; j++) {
3081
if(el->portsUsage[j] != NULL) {
3082
clientPorts[j] += el->portsUsage[j]->clientUses;
3083
serverPorts[j] += el->portsUsage[j]->serverUses;
3090
if(hostsNum >= maxHosts) break;
3099
/* Hosts are now in a contiguous structure (hosts[])... */
3101
sendString("<CENTER>\n");
3102
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON" "DARK_BG"><TH "TH_BG" COLSPAN=2>Service</TH>"
3103
"<TH "TH_BG">Clients</TH><TH "TH_BG">Servers</TH>\n");
3105
for(j=0; j<MAX_ASSIGNED_IP_PORTS; j++)
3106
if((clientPorts[j] > 0) || (serverPorts[j] > 0)) {
3107
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT "DARK_BG">%s</TH><TD "TD_BG" ALIGN=CENTER>%d</TD>"
3108
"<TD "TD_BG">\n", getRowColor(),
3109
getAllPortByNum(j, portBuf, sizeof(portBuf)), j) < 0) BufferTooShort();
3112
if(clientPorts[j] > 0) {
3114
for(idx1=0; idx1<hostsNum; idx1++)
3115
if((hosts[idx1]->portsUsage != NULL)
3116
&& (hosts[idx1]->portsUsage[j] != NULL) /* added 04.03.00 Ralf Amandi */
3117
&& (hosts[idx1]->portsUsage[j]->clientUses > 0)) {
3118
if(snprintf(buf, sizeof(buf), "<li>%s\n",
3119
makeHostLink(hosts[idx1], FLAG_HOSTLINK_TEXT_FORMAT, 1, 0, hostLinkBuf, sizeof(hostLinkBuf))) < 0)
3123
sendString("</UL>");
3125
sendString(" ");
3127
sendString("</TD><TD "TD_BG">");
3129
if(serverPorts[j] > 0) {
3131
for(idx1=0; idx1<hostsNum; idx1++)
3132
if((hosts[idx1]->portsUsage != NULL)
3133
&& (hosts[idx1]->portsUsage[j] != NULL) /* added 04.03.00 Ralf Amandi */
3134
&& (hosts[idx1]->portsUsage[j]->serverUses > 0)) {
3135
if(snprintf(buf, sizeof(buf), "<li>%s\n",
3136
makeHostLink(hosts[idx1], FLAG_HOSTLINK_TEXT_FORMAT, 1, 0, hostLinkBuf, sizeof(hostLinkBuf))) < 0)
3140
sendString("</UL>");
3142
sendString(" ");
3144
sendString("</TD></TR>");
3147
sendString("</TABLE>"TABLE_OFF"<P>\n");
3148
sendString("</CENTER>\n");
3150
printHostColorCode(FALSE, 0);
3152
printFooterHostLink();
3157
/* ********************************** */
3159
void printBar(char *buf, int bufLen,
3160
unsigned short percentageS, /* or the ONLY percentage if R = FLAG_NONSPLITBAR */
3161
unsigned short percentageR,
3162
unsigned short maxPercentage,
3163
unsigned short ratio) {
3165
/* This shouldn't happen */
3166
if(maxPercentage > 100) { maxPercentage = 100; }
3168
if(percentageR == FLAG_NONSPLITBAR) {
3170
if(percentageS > maxPercentage) { percentageS = maxPercentage; }
3172
switch(percentageS) {
3174
if(snprintf(buf, bufLen, "<TD "TD_BG" %s> </TD>\n", getActualRowColor()) < 0)
3178
if(snprintf(buf, bufLen,
3179
"<TD "TD_BG" ALIGN=LEFT>"
3180
"<IMG ALIGN=ABSMIDDLE SRC=\"/gauge.jpg\" ALT=\"%d%%\" WIDTH=%d HEIGHT=12>"
3182
percentageS, ratio*percentageS) < 0)
3187
/* Could happen because of rounding */
3188
if((percentageS+percentageR) > maxPercentage)
3190
if((percentageS+percentageR) > maxPercentage)
3193
switch(percentageS+percentageR) {
3195
if(snprintf(buf, bufLen, "<TD "TD_BG" %s> </TD>\n", getActualRowColor()) < 0)
3199
if(snprintf(buf, bufLen,
3200
"<TD "TD_BG" ALIGN=LEFT>"
3201
"<IMG ALIGN=ABSMIDDLE SRC=\"/gaugeS.jpg\" ALT=\"Sent %d%%\" WIDTH=%d HEIGHT=12>"
3202
"<IMG ALIGN=ABSMIDDLE SRC=\"/gaugeR.jpg\" ALT=\"Received %d%%\" WIDTH=%d HEIGHT=12>"
3204
percentageS, ratio*percentageS, percentageR, ratio*percentageR) < 0)
3213
/* ********************************** */
3215
static int cmpPortsFctn(const void *_a, const void *_b) {
3216
if((_a == NULL) || (_b == NULL))
3221
a = *((PortCounter**)_a);
3222
b = *((PortCounter**)_b);
3224
if((a == NULL) || (b == NULL))
3227
if((a->sent+a->rcvd) > (b->sent+b->rcvd))
3234
/* ********************************** */
3236
void printIpProtocolDistribution(int mode, int revertOrder) {
3238
char buf[2*LEN_GENERAL_WORK_BUFFER], *sign;
3239
float total, partialTotal, remainingTraffic;
3241
char formatBuf[32], formatBuf1[32], formatBuf2[32];
3248
if(mode == FLAG_HOSTLINK_TEXT_FORMAT) {
3249
printSectionTitle("IP Protocol Distribution");
3252
sendString("<CENTER><IMG SRC=\"" CONST_PIE_IPPROTO_RL_DIST CHART_FORMAT "\" "
3253
"alt=\"ipProtocol distribution chart\"><p>\n</CENTER>\n");
3256
printSectionTitle("Local Traffic");
3258
total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local.value+
3259
myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.local.value)/1024;
3263
sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3264
"<TH "TH_BG" WIDTH=150>IP Protocol</TH>"
3265
"<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250>"
3266
"Percentage</TH></TR>\n");
3267
if(total == 0) total = 1; /* Avoids divisions by zero */
3268
remainingTraffic = 0;
3270
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local.value/1024;
3271
percentage = ((float)(partialTotal*100))/((float)total);
3272
printTableEntryPercentage(buf, sizeof(buf), "TCP vs. UDP",
3273
"TCP", "UDP", total, percentage);
3275
sendString("</TABLE>"TABLE_OFF"<P>\n");
3276
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3277
"<TH "TH_BG" WIDTH=150>TCP/UDP Protocol</TH>"
3278
"<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
3279
"Percentage</TH></TR>\n");
3281
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
3282
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].local.value/1024;
3284
if(partialTotal > 0) {
3285
remainingTraffic += partialTotal;
3286
percentage = ((float)(partialTotal*100))/((float)total);
3287
printTableEntry(buf, sizeof(buf), myGlobals.protoIPTrafficInfos[i],
3288
CONST_COLOR_1, partialTotal, percentage);
3292
if(total > remainingTraffic)
3293
remainingTraffic = total - remainingTraffic;
3295
remainingTraffic = 0;
3297
if(remainingTraffic > 0) {
3298
percentage = ((float)(remainingTraffic*100))/((float)total);
3299
printTableEntry(buf, sizeof(buf), "Other TCP/UDP-based Protocols",
3300
CONST_COLOR_1, remainingTraffic, percentage);
3303
sendString("</TABLE>"TABLE_OFF"<P>\n");
3304
sendString("</CENTER>\n");
3307
/* ********************************************************** */
3309
total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote2local.value+
3310
myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.remote2local.value)/1024;
3312
printSectionTitle("Remote to Local Traffic");
3317
sendString("<CENTER>\n");
3318
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3319
"<TH "TH_BG" WIDTH=150>IP Protocol</TH>"
3320
"<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250>"
3321
"Percentage</TH></TR>\n");
3323
if(total == 0) total = 1; /* Avoids divisions by zero */
3324
remainingTraffic = 0;
3326
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote2local.value/1024;
3327
percentage = ((float)(partialTotal*100))/((float)total);
3328
printTableEntryPercentage(buf, sizeof(buf), "TCP vs. UDP",
3329
"TCP", "UDP", total, percentage);
3331
sendString("</TABLE>"TABLE_OFF);
3332
sendString("<P>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3333
"<TH "TH_BG" WIDTH=150>TCP/UDP Protocol</TH>"
3334
"<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
3335
"Percentage</TH></TR>\n");
3337
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
3338
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].remote2local.value/1024;
3340
if(partialTotal > 0) {
3341
remainingTraffic += partialTotal;
3342
percentage = ((float)(partialTotal*100))/((float)total);
3343
printTableEntry(buf, sizeof(buf), myGlobals.protoIPTrafficInfos[i],
3344
CONST_COLOR_1, partialTotal, percentage);
3348
if(total > remainingTraffic)
3349
remainingTraffic = total - remainingTraffic;
3351
remainingTraffic = 0;
3353
if(remainingTraffic > 0) {
3354
percentage = ((float)(remainingTraffic*100))/((float)total);
3355
printTableEntry(buf, sizeof(buf), "Other TCP/UDP-based Protocols",
3356
CONST_COLOR_1, remainingTraffic, percentage);
3358
sendString("</TABLE>"TABLE_OFF"\n<P>\n");
3359
sendString("</CENTER>\n");
3362
/* ********************************************************** */
3364
/* Courtesy of "Burton M. Strauss III" <BStrauss3@attbi.com> */
3366
printSectionTitle("Remote Traffic");
3368
total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote.value+
3369
myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.remote.value)/1024;
3373
sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3374
"<TH "TH_BG" WIDTH=150>IP Protocol</TH>"
3375
"<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250>"
3376
"Percentage</TH></TR>\n");
3377
if(total == 0) total = 1; /* Avoids divisions by zero */
3378
remainingTraffic = 0;
3380
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote.value/1024;
3381
percentage = ((float)(partialTotal*100))/((float)total);
3382
printTableEntryPercentage(buf, sizeof(buf), "TCP vs. UDP",
3383
"TCP", "UDP", total, percentage);
3385
sendString("</TABLE>"TABLE_OFF"\n");
3386
sendString("<P>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3387
"<TH "TH_BG" WIDTH=150>TCP/UDP Protocol</TH>"
3388
"<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
3389
"Percentage</TH></TR>\n");
3391
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
3393
(float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].remote.value/1024;
3395
if(partialTotal > 0) {
3396
remainingTraffic += partialTotal;
3397
percentage = ((float)(partialTotal*100))/((float)total);
3398
printTableEntry(buf, sizeof(buf),
3399
myGlobals.protoIPTrafficInfos[i],
3400
CONST_COLOR_1, partialTotal, percentage);
3404
if(total > remainingTraffic)
3405
remainingTraffic = total - remainingTraffic;
3407
remainingTraffic = 0;
3409
if(remainingTraffic > 0) {
3410
percentage = ((float)(remainingTraffic*100))/((float)total);
3411
printTableEntry(buf, sizeof(buf),
3412
"Other TCP/UDP-based Protocols",
3413
CONST_COLOR_1, remainingTraffic, percentage);
3416
sendString("</TABLE>"TABLE_OFF"<P>\n");
3417
sendString("</CENTER>\n");
3420
/* ********************************************************** */
3422
printSectionTitle("Local to Remote Traffic");
3424
total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local2remote.value+
3425
myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.local2remote.value)/1024;
3429
sendString("<CENTER>\n");
3430
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3431
"<TH "TH_BG" WIDTH=150>IP Protocol</TH>"
3432
"<TH "TH_BG" WIDTH=100>Data</TH>"
3433
"<TH "TH_BG" WIDTH=250>Percentage</TH></TR>\n");
3435
if(total == 0) total = 1; /* Avoids divisions by zero */
3436
remainingTraffic = 0;
3438
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local2remote.value/1024;
3439
percentage = ((float)(partialTotal*100))/((float)total);
3440
printTableEntryPercentage(buf, sizeof(buf), "TCP vs. UDP",
3441
"TCP", "UDP", total, percentage);
3443
sendString("</TABLE>"TABLE_OFF);
3444
sendString("<P>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
3445
"<TH "TH_BG" WIDTH=150>TCP/UDP Protocol</TH>"
3446
"<TH "TH_BG" WIDTH=100>Data</TH>"
3447
"<TH "TH_BG" WIDTH=250 COLSPAN=2>Percentage</TH></TR>\n");
3449
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
3450
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].local2remote.value/1024;
3452
if(partialTotal > 0) {
3453
remainingTraffic += partialTotal;
3454
percentage = ((float)(partialTotal*100))/((float)total);
3455
printTableEntry(buf, sizeof(buf), myGlobals.protoIPTrafficInfos[i],
3456
CONST_COLOR_1, partialTotal, percentage);
3460
if(total > remainingTraffic)
3461
remainingTraffic = total - remainingTraffic;
3463
remainingTraffic = 0;
3465
if(remainingTraffic > 0) {
3466
percentage = ((float)(remainingTraffic*100))/((float)total);
3467
printTableEntry(buf, sizeof(buf), "Other IP-based Protocols",
3468
CONST_COLOR_1, remainingTraffic, percentage);
3470
sendString("</TABLE>"TABLE_OFF"<P>\n");
3471
sendString("</CENTER>\n");
3474
total = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value;
3477
ProtocolsList *protoList = myGlobals.ipProtosList;
3480
while(protoList != NULL) {
3481
if(total > (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtosList[idx1].value)
3482
total -= (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtosList[idx1].value;
3486
idx1++, protoList = protoList->next;
3493
int numProtosFound = 0;
3495
printSectionTitle("Global TCP/UDP Protocol Distribution");
3497
sendString("<CENTER>\n");
3498
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG"><TH "TH_BG" WIDTH=150>"
3499
"TCP/UDP Protocol</TH>"
3500
"<TH "TH_BG" WIDTH=50>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
3501
"Percentage</TH></TR>\n");
3503
remainingTraffic = 0;
3505
for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
3506
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].local.value
3507
+myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].remote.value;
3508
partialTotal += (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].remote2local.value
3509
+myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].local2remote.value;
3511
if(partialTotal > 0) {
3512
remainingTraffic += partialTotal;
3513
percentage = ((float)(partialTotal*100))/((float)total);
3515
printTableEntry(buf, sizeof(buf), myGlobals.protoIPTrafficInfos[i],
3516
CONST_COLOR_1, partialTotal/1024, percentage);
3520
if(total > remainingTraffic)
3521
remainingTraffic = total - remainingTraffic;
3523
remainingTraffic = 0;
3525
if(remainingTraffic > 0) {
3526
percentage = ((float)(remainingTraffic*100))/((float)total);
3527
printTableEntry(buf, sizeof(buf), "Other TCP/UDP-based Protocols",
3528
CONST_COLOR_1, remainingTraffic/1024, percentage);
3532
if(numProtosFound > 0)
3533
sendString("<TR "TR_ON"><TD "TD_BG" COLSPAN=4 ALIGN=CENTER BGCOLOR=white>"
3534
"<IMG SRC=\"" CONST_BAR_IPPROTO_DIST CHART_FORMAT "\" "
3535
"alt=\"Global ipProtocol distribution chart\"></TD></TR>\n");
3537
sendString("</TABLE>"TABLE_OFF"<P>\n");
3539
/* *********************** */
3541
if(remainingTraffic > 0) {
3542
PortCounter **ipPorts;
3545
ipPorts = (PortCounter**)calloc(MAX_IP_PORT, sizeof(PortCounter*));
3547
for(i=0; i<MAX_IP_PORT; i++) {
3548
if(myGlobals.device[myGlobals.actualReportDeviceId].ipPorts[i] != NULL) {
3549
ipPorts[idx] = myGlobals.device[myGlobals.actualReportDeviceId].ipPorts[i];
3555
printSectionTitle("TCP/UDP Traffic Port Distribution:<br>Last Minute View");
3557
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON" "DARK_BG">"
3558
"<TH "TH_BG" colspan=2>TCP/UDP Port</TH>"
3559
"<TH "TH_BG">Total</TH><TH "TH_BG">Sent</TH><TH "TH_BG">Rcvd</TH></TR>");
3561
qsort(ipPorts, idx, sizeof(PortCounter**), cmpPortsFctn);
3563
if(idx > 32) idx = 32; /* Limit to 32 entries max */
3565
for(i=0; i<idx; i++) {
3566
if(ipPorts[i] != NULL) {
3569
char *symPort = getAllPortByNum(ipPorts[i]->port, portBuf, sizeof(portBuf));
3571
if(symPort == NULL) symPort = "";
3573
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
3574
"<TH "TH_BG" ALIGN=LEFT><A HREF=\"" CONST_SHOW_PORT_TRAFFIC_HTML "?port=%d\">%s</A></th><td align=right>%d</td>"
3575
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
3576
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
3577
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
3580
ipPorts[i]->port, symPort, ipPorts[i]->port,
3581
formatBytes(ipPorts[i]->sent+ipPorts[i]->rcvd, 1, formatBuf, sizeof(formatBuf)),
3582
formatBytes(ipPorts[i]->sent, 1, formatBuf1, sizeof(formatBuf1)),
3583
formatBytes(ipPorts[i]->rcvd, 1, formatBuf2, sizeof(formatBuf2))
3584
) < 0) BufferTooShort();
3589
sendString("<tr><td align=left "DARK_BG" colspan=5>Notes:<ul>"
3590
"<li>sum(total traffic per port) = 2*(total IP traffic)"
3591
"<br>because the traffic per port is counted twice (sent and received)"
3592
"<li>This report includes broadcast packets</ul></td></tr>\n");
3595
sendString("</TABLE>"TABLE_OFF"<P></center>\n");
3597
sendString("<p>This extract is just a sample of the packets ntop has seen.</p>");
3599
sendString("<p>Note:This report includes broadcast packets</p>\n");
3600
sendString("</CENTER>\n");
3606
/* ************************ */
3608
void printProtoTraffic(void) {
3610
char buf[LEN_GENERAL_WORK_BUFFER], formatBuf[32];
3612
total = myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value/1024; /* total is expressed in KBytes.value */
3617
printSectionTitle("Global Protocol Distribution");
3618
sendString("<CENTER>\n");
3619
sendString("<P>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON" "DARK_BG"><TH "TH_BG" WIDTH=150>Protocol</TH>"
3620
"<TH "TH_BG" WIDTH=50>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>Percentage</TH></TR>\n");
3622
perc = 100*((float)myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value/
3623
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value);
3624
if(perc > 100) perc = 100;
3626
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" WIDTH=150 ALIGN=LEFT "DARK_BG">IP</TH>"
3627
"<TD "TD_BG" WIDTH=50 ALIGN=RIGHT>%s"
3628
"</td><td align=right WIDTH=50>%.1f%%</TD><TD "TD_BG" WIDTH=200>"
3629
"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%%\">",
3631
formatBytes(myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value, 1,
3632
formatBuf, sizeof(formatBuf)),
3637
printTableEntry(buf, sizeof(buf), "TCP", CONST_COLOR_1,
3638
(float)myGlobals.device[myGlobals.actualReportDeviceId].tcpBytes.value/1024,
3639
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].tcpBytes.value/
3640
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value));
3641
printTableEntry(buf, sizeof(buf), "UDP", CONST_COLOR_1,
3642
(float)myGlobals.device[myGlobals.actualReportDeviceId].udpBytes.value/1024,
3643
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].udpBytes.value/
3644
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value));
3645
printTableEntry(buf, sizeof(buf), "ICMP", CONST_COLOR_1,
3646
(float)myGlobals.device[myGlobals.actualReportDeviceId].icmpBytes.value/1024,
3647
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].icmpBytes.value/
3648
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value));
3650
printTableEntry(buf, sizeof(buf), "ICMPv6", CONST_COLOR_1,
3651
(float)myGlobals.device[myGlobals.actualReportDeviceId].icmp6Bytes.value/1024,
3652
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].icmp6Bytes.value/
3653
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value));
3655
ProtocolsList *protoList = myGlobals.ipProtosList;
3658
while(protoList != NULL) {
3659
printTableEntry(buf, sizeof(buf), protoList->protocolName, CONST_COLOR_1,
3660
(float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtosList[idx].value/1024,
3661
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtosList[idx].value/
3662
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value));
3663
idx++, protoList = protoList->next;
3667
printTableEntry(buf, sizeof(buf), "Other IP", CONST_COLOR_1,
3668
(float)myGlobals.device[myGlobals.actualReportDeviceId].otherIpBytes.value/1024,
3669
((float)myGlobals.device[myGlobals.actualReportDeviceId].otherIpBytes.value/
3670
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value));
3672
sendString("</TABLE>"TABLE_OFF"</TR>");
3674
printTableEntry(buf, sizeof(buf), "(R)ARP", CONST_COLOR_1,
3675
(float)myGlobals.device[myGlobals.actualReportDeviceId].arpRarpBytes.value/1024,
3676
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].arpRarpBytes.value/
3677
myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value));
3678
printTableEntry(buf, sizeof(buf), "DLC", CONST_COLOR_1,
3679
(float)myGlobals.device[myGlobals.actualReportDeviceId].dlcBytes.value/1024,
3680
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].dlcBytes.value/
3681
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3682
printTableEntry(buf, sizeof(buf), "IPX", CONST_COLOR_1,
3683
(float)myGlobals.device[myGlobals.actualReportDeviceId].ipxBytes.value/1024,
3684
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].ipxBytes.value/
3685
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3686
printTableEntry(buf, sizeof(buf), "Decnet", CONST_COLOR_1,
3687
(float)myGlobals.device[myGlobals.actualReportDeviceId].decnetBytes.value/1024,
3688
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].decnetBytes.value/
3689
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3690
printTableEntry(buf, sizeof(buf), "AppleTalk", CONST_COLOR_1,
3691
(float)myGlobals.device[myGlobals.actualReportDeviceId].atalkBytes.value/1024,
3692
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].atalkBytes.value/
3693
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3694
printTableEntry(buf, sizeof(buf), "NetBios", CONST_COLOR_1,
3695
(float)myGlobals.device[myGlobals.actualReportDeviceId].netbiosBytes.value/1024,
3696
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].netbiosBytes.value/
3697
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3698
printTableEntry(buf, sizeof(buf), "OSI", CONST_COLOR_1,
3699
(float)myGlobals.device[myGlobals.actualReportDeviceId].osiBytes.value/1024,
3700
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].osiBytes.value/
3701
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3702
printTableEntry(buf, sizeof(buf), "IPv6", CONST_COLOR_1,
3703
(float)myGlobals.device[myGlobals.actualReportDeviceId].ipv6Bytes.value/1024,
3704
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].ipv6Bytes.value/
3705
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3706
printTableEntry(buf, sizeof(buf), "STP", CONST_COLOR_1,
3707
(float)myGlobals.device[myGlobals.actualReportDeviceId].stpBytes.value/1024,
3708
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].stpBytes.value/
3709
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3711
printTableEntry(buf, sizeof(buf), "Other", CONST_COLOR_1,
3712
(float)myGlobals.device[myGlobals.actualReportDeviceId].otherBytes.value/1024,
3713
100*((float)myGlobals.device[myGlobals.actualReportDeviceId].otherBytes.value/
3714
myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value));
3717
sendString("<TR "TR_ON"><TD "TD_BG" COLSPAN=4 ALIGN=CENTER BGCOLOR=white>"
3718
"<IMG SRC=\"" CONST_BAR_ALLPROTO_DIST CHART_FORMAT "\" "
3719
"alt=\"global protocol distribution chart\"></TD></TR>\n");
3722
sendString("</TABLE>"TABLE_OFF"<P></CENTER>\n");
3725
/* ************************ */
3727
void printIpTrafficMatrix(void) {
3728
int i, j, numEntries=0, numConsecutiveEmptyCells;
3729
char buf[LEN_GENERAL_WORK_BUFFER], formatBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
3731
Counter minTraffic=(Counter)LONG_MAX, maxTraffic=0, avgTraffic;
3732
Counter avgTrafficLow, avgTrafficHigh, tmpCounter;
3734
printHTMLheader("IP Subnet Traffic Matrix", NULL, 0);
3736
if(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix == NULL) {
3737
printFlagedWarning("<I>Traffic matrix is not available for the selected network interface</I>");
3741
activeHosts = (short*)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numHosts*sizeof(short), "printIpTrafficMatrix");
3742
if(activeHosts == NULL)
3745
for(i=0; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; i++) {
3748
for(j=0; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; j++) {
3749
int id = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
3751
if(((myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[id] != NULL)
3752
&& (myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[id]->bytesSent.value != 0))
3753
|| ((myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[id] != NULL)
3754
&& (myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[id]->bytesRcvd.value != 0))) {
3761
if(activeHosts[i] == 1) {
3762
if(numEntries == 1) {
3763
sendString("<CENTER>\n");
3764
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG"><SMALL> F "
3765
" To<br> r<br> o<br> m</SMALL></TH>\n");
3768
if(snprintf(buf, sizeof(buf), "<TH "TH_BG" ALIGN=CENTER "DARK_BG"><SMALL>%s</SMALL></TH>",
3769
getHostName(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrixHosts[i],
3770
1, hostLinkBuf, sizeof(hostLinkBuf))) < 0)
3776
if(numEntries == 0) {
3781
sendString("</TR>\n");
3783
for(i=0; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; i++)
3784
for(j=0; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; j++) {
3785
int idx = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
3787
if(((myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx] != NULL)
3788
&& ((myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesSent.value != 0)
3789
|| (myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesRcvd.value != 0)))) {
3790
if(minTraffic > myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesSent.value)
3791
minTraffic = myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesSent.value;
3792
if(minTraffic > myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesRcvd.value)
3793
minTraffic = myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesRcvd.value;
3794
if(maxTraffic < myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesSent.value)
3795
maxTraffic = myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesSent.value;
3796
if(maxTraffic < myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesRcvd.value)
3797
maxTraffic = myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesRcvd.value;
3801
avgTraffic = (Counter)(((float)minTraffic+(float)maxTraffic)/2);
3802
avgTrafficLow = (avgTraffic*15)/100; /* 15% of the average */
3803
avgTrafficHigh = 2*(maxTraffic/3); /* 75% of max traffic */
3806
for(i=0; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; i++)
3807
if(activeHosts[i] == 1) {
3808
numConsecutiveEmptyCells=0;
3810
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT "DARK_BG"><SMALL>", getRowColor()) < 0)
3814
sendString(makeHostLink(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrixHosts[i],
3815
FLAG_HOSTLINK_TEXT_FORMAT, 1, 0, hostLinkBuf, sizeof(hostLinkBuf)));
3816
sendString("</SMALL></TH>");
3818
for(j=0; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; j++) {
3819
int idx = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
3822
strcmp(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrixHosts[i]->hostNumIpAddress,
3824
numConsecutiveEmptyCells++;
3825
else if(activeHosts[j] == 1) {
3826
if(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx] == NULL)
3827
numConsecutiveEmptyCells++;
3829
if(numConsecutiveEmptyCells > 0) {
3830
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d> </TD>\n",
3831
numConsecutiveEmptyCells) < 0) BufferTooShort();
3833
numConsecutiveEmptyCells = 0;
3836
tmpCounter = myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesSent.value+
3837
myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx]->bytesRcvd.value;
3838
/* Fix below courtesy of Danijel Doriae <danijel.doric@industrogradnja.tel.hr> */
3839
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER %s>"
3840
"<A HREF=# onMouseOver=\"window.status='"
3841
"%s';return true\" onMouseOut="
3842
"\"window.status='';return true\"><SMALL>%s</SMALL></A></TH>\n",
3843
calculateCellColor(tmpCounter, avgTrafficLow, avgTrafficHigh),
3844
buildHTMLBrowserWindowsLabel(i, j, TRUE),
3845
formatBytes(tmpCounter, 1, formatBuf, sizeof(formatBuf))) < 0)
3852
if(numConsecutiveEmptyCells > 0) {
3853
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d> </TD>\n",
3854
numConsecutiveEmptyCells) < 0)
3857
numConsecutiveEmptyCells = 0;
3860
sendString("</TR>\n");
3863
sendString("</TABLE>"TABLE_OFF"\n<P>\n");
3864
sendString("</CENTER>\n");
3866
printFooterHostLink();
3871
/* ************************ */
3873
void printThptStatsMatrix(int sortedColumn) {
3875
char label[32], label1[32], buf[LEN_GENERAL_WORK_BUFFER],
3876
formatBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
3881
printHTMLheader("Network Load Statistics Matrix", NULL, 0);
3883
switch(sortedColumn) {
3885
sendString("<CENTER>\n");
3886
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON" "DARK_BG">"
3887
"<TH "TH_BG">Sampling Period</TH>"
3888
"<TH "TH_BG">Average Thpt</TH>"
3889
"<TH "TH_BG">Top Hosts Sent Thpt</TH>"
3890
"<TH "TH_BG">Top Hosts Rcvd Thpt</TH></TR>\n");
3892
for(i=0; i<60; i++) {
3893
if(myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].trafficValue == 0)
3896
tmpTime = myGlobals.actTime-(i*60);
3897
strftime(label, sizeof(label), CONST_TOD_NOSEC_TIMESPEC, localtime_r(&tmpTime, &t));
3898
tmpTime = myGlobals.actTime-((i+1)*60);
3899
strftime(label1, sizeof(label), CONST_TOD_NOSEC_TIMESPEC, localtime_r(&tmpTime, &t));
3900
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=CENTER>"
3901
"<B>%s - %s</B></TH>"
3902
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=LEFT>"
3903
"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=100%%>",
3904
getRowColor(), label1, label,
3905
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
3906
last60MinutesThpt[i].trafficValue, 1,
3907
formatBuf, sizeof(formatBuf))) < 0)
3913
/* ************************* */
3915
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].topHostSentSerial)) {
3918
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].
3919
last60MinutesThpt[i].topHostSentSerial, myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
3920
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
3921
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
3922
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
3923
last60MinutesThpt[i].topSentTraffic.value, 1,
3924
formatBuf, sizeof(formatBuf))) < 0)
3926
sendString(buf); dataSent = 1;
3930
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].secondHostSentSerial)) {
3933
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].
3934
last60MinutesThpt[i].secondHostSentSerial, myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
3935
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
3936
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
3937
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
3938
last60MinutesThpt[i].secondSentTraffic.value, 1,
3939
formatBuf, sizeof(formatBuf))) < 0)
3941
sendString(buf); dataSent = 1;
3945
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].thirdHostSentSerial)) {
3948
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].
3949
last60MinutesThpt[i].thirdHostSentSerial, myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
3950
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
3951
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
3952
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
3953
last60MinutesThpt[i].thirdSentTraffic.value, 1,
3954
formatBuf, sizeof(formatBuf))) < 0)
3956
sendString(buf); dataSent = 1;
3960
/* ************************* */
3962
if(!dataSent) sendString(" ");
3963
sendString("</TABLE>"TABLE_OFF"</TD><TD "TD_BG" ALIGN=LEFT><TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=100%%>\n");
3966
/* ************************* */
3968
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].topHostRcvdSerial)) {
3971
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].
3972
last60MinutesThpt[i].topHostRcvdSerial, myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
3973
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
3974
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
3975
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
3976
last60MinutesThpt[i].topRcvdTraffic.value, 1,
3977
formatBuf, sizeof(formatBuf))) < 0)
3979
sendString(buf); dataSent = 1;
3983
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].secondHostRcvdSerial)) {
3986
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].
3987
last60MinutesThpt[i].secondHostRcvdSerial, myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
3988
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
3989
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
3990
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
3991
last60MinutesThpt[i].secondRcvdTraffic.value, 1,
3992
formatBuf, sizeof(formatBuf))) < 0)
3994
sendString(buf); dataSent = 1;
3998
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].thirdHostRcvdSerial)) {
4001
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].
4002
last60MinutesThpt[i].thirdHostRcvdSerial, myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
4003
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4004
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
4005
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4006
last60MinutesThpt[i].thirdRcvdTraffic.value, 1,
4007
formatBuf, sizeof(formatBuf))) < 0)
4009
sendString(buf); dataSent = 1;
4013
/* ************************* */
4015
if(!dataSent) sendString(" ");
4016
sendString("</TABLE></TD></TR>\n");
4021
if(myGlobals.device[myGlobals.actualReportDeviceId].numThptSamples < 60) {
4025
sendString("<CENTER>\n");
4026
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON">"
4027
"<TH "TH_BG">Sampling Period</TH><TH "TH_BG">Average Thpt</TH>"
4028
"<TH "TH_BG">Top Thpt Sent Hosts</TH><TH "TH_BG">Top Rcvd Sent Hosts</TH>"
4031
for(i=0; i<24; i++) {
4032
if(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].trafficValue == 0)
4035
tmpTime = myGlobals.actTime-(i*60*60);
4036
strftime(label, sizeof(label), CONST_TOD_NOSEC_TIMESPEC, localtime_r(&tmpTime, &t));
4037
tmpTime = myGlobals.actTime-((i+1)*60*60);
4038
strftime(label1, sizeof(label1), CONST_TOD_NOSEC_TIMESPEC, localtime_r(&tmpTime, &t));
4039
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TD "TD_BG" ALIGN=CENTER><B>%s - %s</B></TH>"
4040
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=LEFT "DARK_BG">"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">",
4041
getRowColor(), label, label1,
4042
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4043
last24HoursThpt[i].trafficValue, 1,
4044
formatBuf, sizeof(formatBuf))) < 0)
4048
/* ************************* */
4050
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].topHostSentSerial)) {
4053
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].topHostSentSerial,
4054
myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
4055
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4056
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
4057
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4058
last24HoursThpt[i].topSentTraffic.value, 1,
4059
formatBuf, sizeof(formatBuf))) < 0)
4065
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].secondHostSentSerial)) {
4068
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].secondHostSentSerial,
4069
myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
4070
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4071
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
4072
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4073
last24HoursThpt[i].secondSentTraffic.value, 1,
4074
formatBuf, sizeof(formatBuf))) < 0)
4080
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].thirdHostSentSerial)) {
4083
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].thirdHostSentSerial,
4084
myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
4085
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4086
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
4087
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4088
last24HoursThpt[i].thirdSentTraffic.value, 1,
4089
formatBuf, sizeof(formatBuf))) < 0)
4095
/* ************************* */
4097
sendString(" ");
4098
sendString("</TABLE>"TABLE_OFF"</TD><TD "TD_BG" ALIGN=LEFT "DARK_BG">"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n");
4100
/* ************************* */
4102
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].topHostRcvdSerial)) {
4105
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].topHostRcvdSerial,
4106
myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
4107
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4108
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
4109
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4110
last24HoursThpt[i].topRcvdTraffic.value, 1,
4111
formatBuf, sizeof(formatBuf))) < 0)
4117
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].secondHostRcvdSerial)) {
4120
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].secondHostRcvdSerial,
4121
myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
4122
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4123
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
4124
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4125
last24HoursThpt[i].secondRcvdTraffic.value, 1,
4126
formatBuf, sizeof(formatBuf))) < 0)
4132
if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].thirdHostRcvdSerial)) {
4135
if((el = quickHostLink(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].thirdHostRcvdSerial,
4136
myGlobals.actualReportDeviceId, &tmpEl)) != NULL) {
4137
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4138
makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
4139
formatThroughput(myGlobals.device[myGlobals.actualReportDeviceId].
4140
last24HoursThpt[i].thirdRcvdTraffic.value, 1,
4141
formatBuf, sizeof(formatBuf))) < 0)
4147
/* ************************* */
4149
sendString(" ");
4150
sendString("</TABLE>"TABLE_OFF"</TD></TR>\n");
4156
sendString("</TABLE>"TABLE_OFF"</CENTER>\n");
4159
/* ************************ */
4161
void printThptStats(int sortedColumn _UNUSED_) {
4162
char tmpBuf[128], formatBuf[32], formatBuf1[32];
4164
printHTMLheader("Network Load Statistics", NULL, 0);
4166
if(myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
4167
printFlagedWarning("<I>Network load statistics are not available for virtual interfaces</I>");
4171
if(myGlobals.device[myGlobals.actualReportDeviceId].numThptSamples == 0) {
4176
sendString("<CENTER>\n");
4179
sendString("<A HREF=\"" CONST_THPT_STATS_MATRIX_HTML "?col=1\" BORDER=0 BGCOLOR=white>"
4180
"<IMG SRC=\"" CONST_THROUGHPUT_GRAPH CHART_FORMAT "?col=1\" alt=\"Current Hour throughput chart\"></A><BR>\n");
4183
if(snprintf(tmpBuf, sizeof(tmpBuf), "<H4>Time [ %s through %s]</H4>",
4184
formatTimeStamp(0, 0, 60, formatBuf, sizeof(formatBuf)),
4185
formatTimeStamp(0, 0, 0, formatBuf1, sizeof(formatBuf1))) < 0) BufferTooShort();
4189
if(myGlobals.device[myGlobals.actualReportDeviceId].numThptSamples > 60) {
4191
sendString("<P><A HREF=\"" CONST_THPT_STATS_MATRIX_HTML "?col=2\" BORDER=0 BGCOLOR=white>"
4192
"<IMG SRC=\"" CONST_THROUGHPUT_GRAPH CHART_FORMAT "?col=2\" alt=\"Current Day throughput chart\"></A><BR>\n");
4194
if(snprintf(tmpBuf, sizeof(tmpBuf), "<H4>Time [ %s through %s]</H4>",
4195
formatTimeStamp(0, 24, 0, formatBuf, sizeof(formatBuf)),
4196
formatTimeStamp(0, 0, 0, formatBuf1, sizeof(formatBuf1))) < 0) BufferTooShort();
4201
if(myGlobals.device[myGlobals.actualReportDeviceId].numThptSamples > 1440 /* 60 * 24 */) {
4202
sendString("<P><IMG SRC=\"" CONST_THROUGHPUT_GRAPH CHART_FORMAT "?col=3\" alt=\"Current 30day throughput chart><BR>\n");
4203
if(snprintf(tmpBuf, sizeof(tmpBuf), "<H4>Time [ %s through %s]</H4>",
4204
formatTimeStamp(30, 0, 0, formatBuf, sizeof(formatBuf)),
4205
formatTimeStamp( 0, 0, 0, formatBuf1, sizeof(formatBuf1))) < 0)
4212
sendString("</CENTER>\n");
4215
/* ************************ */
4217
static int cmpStatsFctn(const void *_a, const void *_b) {
4218
DomainStats *a = (DomainStats *)_a;
4219
DomainStats *b = (DomainStats *)_b;
4223
if((a == NULL) && (b != NULL)) {
4224
traceEvent(CONST_TRACE_WARNING, "cmpStatsFctn() (1)");
4226
} else if((a != NULL) && (b == NULL)) {
4227
traceEvent(CONST_TRACE_WARNING, "cmpStatsFctn() (2)");
4229
} else if((a == NULL) && (b == NULL)) {
4230
traceEvent(CONST_TRACE_WARNING, "cmpStatsFctn() (3)");
4234
switch(myGlobals.columnSort) {
4235
case 1: /* Domain Flag */
4236
/* We don't worry about whether this is single or multi domain, since if it is a single
4237
domain, our fallback to hostResolvedName will rule anyway.
4239
rc = cmpFctnLocationName(a, b);
4241
case 2: a_ = a->bytesSent.value, b_ = b->bytesSent.value; break;
4242
case 3: a_ = a->bytesRcvd.value, b_ = b->bytesRcvd.value; break;
4243
case 4: a_ = a->tcpSent.value , b_ = b->tcpSent.value; break;
4244
case 5: a_ = a->tcpRcvd.value , b_ = b->tcpRcvd.value; break;
4245
case 6: a_ = a->udpSent.value , b_ = b->udpSent.value; break;
4246
case 7: a_ = a->udpRcvd.value , b_ = b->udpRcvd.value; break;
4247
case 8: a_ = a->icmpSent.value , b_ = b->icmpSent.value; break;
4248
case 9: a_ = a->icmpRcvd.value , b_ = b->icmpRcvd.value; break;
4249
case 10:a_ = a->icmp6Sent.value , b_ = b->icmp6Sent.value; break;
4250
case 11:a_ = a->icmp6Rcvd.value , b_ = b->icmp6Rcvd.value; break;
4253
rc = cmpFctnResolvedName(&(a->domainHost), &(b->domainHost));
4265
/* ****************************************** */
4267
/* if myGlobals.domainName == NULL -> print all domains */
4268
void printDomainStats(char* domainName, int sortedColumn, int revertOrder, int pageNum) {
4269
u_int idx, tmpIdx, numEntries=0, printedEntries=0, len, maxHosts;
4270
u_short keyValue=0, i;
4272
char buf[LEN_GENERAL_WORK_BUFFER];
4273
DomainStats **stats, *tmpStats, *statsEntry;
4274
char htmlAnchor[2*LEN_GENERAL_WORK_BUFFER], htmlAnchor1[2*LEN_GENERAL_WORK_BUFFER],
4275
*sign, *arrowGif, *arrow[48], *theAnchor[48];
4276
Counter totBytesSent=0, totBytesRcvd=0;
4277
char formatBuf[32], formatBuf1[32], formatBuf2[32], formatBuf3[32], formatBuf4[32],
4278
formatBuf5[32], formatBuf6[32], formatBuf7[32], formatBuf8[32], formatBuf9[32],
4279
hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
4281
if(domainName == NULL) {
4282
if(snprintf(buf, sizeof(buf), "Statistics for all Domains") < 0)
4285
if(snprintf(buf, sizeof(buf), "Statistics for hosts in Domain <i>%s</i>", domainName) < 0)
4288
printHTMLheader(buf, NULL, 0);
4290
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
4291
len = sizeof(DomainStats)*maxHosts;
4292
tmpStats = (DomainStats*)mallocAndInitWithReportWarn(len, "printDomainStats");
4293
if(tmpStats == NULL)
4296
/* Fix below courtesy of Francis Pintos <francis@arhl.com.hk> */
4297
len = sizeof(DomainStats**)*maxHosts;
4298
stats = (DomainStats**)mallocAndInitWithReportWarn(len, "printDomainStats(2)");
4302
/* traceEvent(CONST_TRACE_INFO, "'%s' '%d' '%d'", domainName, sortedColumn, revertOrder); */
4306
arrowGif = " " CONST_IMG_ARROW_UP;
4309
arrowGif = " " CONST_IMG_ARROW_DOWN;
4312
for(el=getFirstHost(myGlobals.actualReportDeviceId);
4313
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
4316
if((el->dnsDomainValue == NULL)
4317
|| (el->dnsDomainValue[0] == '\0')
4318
|| (el->ip2ccValue == NULL)
4319
|| (el->hostResolvedName[0] == '\0')
4320
|| (el->ip2ccValue == '\0')
4321
|| broadcastHost(el)
4324
} else if((domainName != NULL)
4325
&& (strcmp(el->dnsDomainValue, domainName) != 0)) {
4329
if(domainName == NULL) {
4330
for(keyValue=0, tmpIdx=0; el->dnsDomainValue[tmpIdx] != '\0'; tmpIdx++)
4331
keyValue += (tmpIdx+1)*(u_short)el->dnsDomainValue[tmpIdx];
4333
keyValue %= maxHosts;
4335
while((stats[keyValue] != NULL)
4336
&& (strcasecmp(stats[keyValue]->domainHost->dnsDomainValue, el->dnsDomainValue) != 0))
4337
keyValue = (keyValue+1) % maxHosts;
4339
if(stats[keyValue] != NULL)
4340
statsEntry = stats[keyValue];
4342
statsEntry = &tmpStats[numEntries++];
4343
memset(statsEntry, 0, sizeof(DomainStats));
4344
statsEntry->domainHost = el;
4345
stats[keyValue] = statsEntry;
4346
/* traceEvent(CONST_TRACE_INFO, "[%d] %s/%s", numEntries, el->dnsDomainValue, el->ip2ccValue); */
4349
statsEntry = &tmpStats[numEntries++];
4350
memset(statsEntry, 0, sizeof(DomainStats));
4351
statsEntry->domainHost = el;
4352
stats[keyValue++] = statsEntry;
4355
totBytesSent += el->bytesSent.value;
4356
statsEntry->bytesSent.value += el->bytesSent.value;
4357
statsEntry->bytesRcvd.value += el->bytesRcvd.value;
4358
totBytesRcvd += el->bytesRcvd.value;
4359
statsEntry->tcpSent.value += el->tcpSentLoc.value + el->tcpSentRem.value;
4360
statsEntry->udpSent.value += el->udpSentLoc.value + el->udpSentRem.value;
4361
statsEntry->icmpSent.value += el->icmpSent.value;
4362
statsEntry->icmp6Sent.value += el->icmp6Sent.value;
4363
statsEntry->tcpRcvd.value += el->tcpRcvdLoc.value + el->tcpRcvdFromRem.value;
4364
statsEntry->udpRcvd.value += el->udpRcvdLoc.value + el->udpRcvdFromRem.value;
4365
statsEntry->icmpRcvd.value += el->icmpRcvd.value;
4366
statsEntry->icmp6Rcvd.value += el->icmp6Rcvd.value;
4368
if(numEntries >= maxHosts) break;
4371
if(numEntries == 0) {
4373
free(tmpStats); free(stats);
4377
myGlobals.columnSort = sortedColumn;
4379
qsort(tmpStats, numEntries, sizeof(DomainStats), cmpStatsFctn);
4381
/* avoid division by zero */
4382
if(totBytesSent == 0)
4384
if(totBytesRcvd == 0)
4387
if(domainName == NULL) {
4388
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", CONST_DOMAIN_STATS_HTML, sign) < 0)
4390
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", CONST_DOMAIN_STATS_HTML) < 0)
4393
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?dom=%s&col=%s",
4394
CONST_DOMAIN_STATS_HTML, domainName, sign) < 0)
4396
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?dom=%s&col=",
4397
CONST_DOMAIN_STATS_HTML, domainName) < 0)
4401
for(i=0; i<=15; i++)
4402
if(abs(myGlobals.columnSort) == i)
4403
arrow[i] = arrowGif, theAnchor[i] = htmlAnchor;
4405
arrow[i] = "", theAnchor[i] = htmlAnchor1;
4407
/* Split below courtesy of Andreas Pfaller <apfaller@yahoo.com.au> */
4408
sendString("<CENTER>\n" TABLE_ON "<TABLE BORDER=1 "TABLE_DEFAULTS">");
4409
if(snprintf(buf, sizeof(buf),
4410
"<TR "TR_ON" "DARK_BG">"
4411
"<TH "TH_BG" rowspan=\"3\">%s0>Name%s</A></TH>"
4412
"<TH "TH_BG" rowspan=\"3\">%s1>Domain%s</A></TH>"
4413
"<TH "TH_BG" colspan=\"8\">TCP/IP</A></TH>"
4414
"<TH "TH_BG" colspan=\"4\">ICMP</A></TH>\n",
4415
theAnchor[0], arrow[0],
4416
theAnchor[1], arrow[1]) < 0)
4420
sendString( "<TR "TR_ON" "DARK_BG">"
4421
"<TH "TH_BG" colspan=\"4\">TCP</A></TH>"
4422
"<TH "TH_BG" colspan=\"4\">UDP</A></TH>"
4423
"<TH "TH_BG" colspan=\"2\">IPv4</A></TH>"
4424
"<TH "TH_BG" colspan=\"2\">IPv6</A></TH></TR>\n");
4426
if(snprintf(buf, sizeof(buf),
4427
"<TR "TR_ON" "DARK_BG">"
4428
"<TH "TH_BG" colspan=\"2\">%s2>Sent%s</A></TH>"
4429
"<TH "TH_BG" colspan=\"2\">%s3>Rcvd%s</A></TH>"
4430
"<TH "TH_BG">%s4>Sent%s</A></TH>"
4431
"<TH "TH_BG">%s5>Rcvd%s</A></TH>"
4432
"<TH "TH_BG">%s6>Sent%s</A></TH>"
4433
"<TH "TH_BG">%s7>Rcvd%s</A></TH>"
4434
"<TH "TH_BG">%s8>Sent%s</A></TH>"
4435
"<TH "TH_BG">%s9>Rcvd%s</A></TH>"
4436
"<TH "TH_BG">%s10>Sent%s</A></TH>"
4437
"<TH "TH_BG">%s11>Rcvd%s</A></TH></TR>\n",
4438
theAnchor[2], arrow[2],
4439
theAnchor[3], arrow[3],
4440
theAnchor[4], arrow[4],
4441
theAnchor[5], arrow[5],
4442
theAnchor[6], arrow[6],
4443
theAnchor[7], arrow[7],
4444
theAnchor[8], arrow[8],
4445
theAnchor[9], arrow[9],
4446
theAnchor[10], arrow[10],
4447
theAnchor[11], arrow[11]) < 0)
4451
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
4453
statsEntry = &tmpStats[numEntries-idx-1];
4455
statsEntry = &tmpStats[idx];
4457
if(domainName == NULL) {
4458
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?dom=%s>%s</A>",
4459
CONST_DOMAIN_STATS_HTML, statsEntry->domainHost->dnsDomainValue,
4460
statsEntry->domainHost->dnsDomainValue) < 0)
4463
char tmpBuf[64], *hostLink;
4466
accessAddrResMutex("getHostIcon");
4468
blankId = strlen(statsEntry->domainHost->hostResolvedName)-
4469
strlen(statsEntry->domainHost->dnsDomainValue)-1;
4471
strncpy(tmpBuf, statsEntry->domainHost->hostResolvedName, sizeof(tmpBuf));
4473
releaseAddrResMutex();
4476
&& (strcmp(&tmpBuf[blankId+1], domainName) == 0))
4477
tmpBuf[blankId] = '\0';
4479
hostLink = makeHostLink(statsEntry->domainHost, FLAG_HOSTLINK_TEXT_FORMAT, 1,
4480
0, hostLinkBuf, sizeof(hostLinkBuf));
4482
len = strlen(hostLink); if(len >= sizeof(htmlAnchor)) len = sizeof(htmlAnchor)-1;
4483
strncpy(htmlAnchor, hostLink, len);
4484
htmlAnchor[len] = '\0';
4488
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT "DARK_BG">%s</TH><TD "TD_BG" ALIGN=CENTER>%s</TD>"
4489
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%%</TD>"
4490
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%%</TD>"
4491
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
4492
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4493
getRowColor(), htmlAnchor,
4494
getHostCountryIconURL(statsEntry->domainHost),
4495
formatBytes(statsEntry->bytesSent.value, 1, formatBuf, sizeof(formatBuf)),
4496
(100*((float)statsEntry->bytesSent.value/(float)totBytesSent)),
4497
formatBytes(statsEntry->bytesRcvd.value, 1, formatBuf1, sizeof(formatBuf1)),
4498
(100*((float)statsEntry->bytesRcvd.value/(float)totBytesRcvd)),
4499
formatBytes(statsEntry->tcpSent.value, 1, formatBuf2, sizeof(formatBuf2)),
4500
formatBytes(statsEntry->tcpRcvd.value, 1, formatBuf3, sizeof(formatBuf3)),
4501
formatBytes(statsEntry->udpSent.value, 1, formatBuf4, sizeof(formatBuf4)),
4502
formatBytes(statsEntry->udpRcvd.value, 1, formatBuf5, sizeof(formatBuf5)),
4503
formatBytes(statsEntry->icmpSent.value, 1, formatBuf6, sizeof(formatBuf6)),
4504
formatBytes(statsEntry->icmpRcvd.value, 1, formatBuf7, sizeof(formatBuf7)),
4505
formatBytes(statsEntry->icmp6Sent.value, 1, formatBuf8, sizeof(formatBuf8)),
4506
formatBytes(statsEntry->icmp6Rcvd.value, 1, formatBuf9, sizeof(formatBuf9))
4507
) < 0) BufferTooShort();
4510
/* Avoid huge tables */
4511
if(printedEntries++ > myGlobals.maxNumLines)
4515
sendString("</TABLE>"TABLE_OFF"</HTML>\n");
4516
sendString("</CENTER>\n");
4518
if(domainName != NULL) {
4519
if(snprintf(buf, sizeof(buf), "%s?dom=%s", CONST_DOMAIN_STATS_HTML, domainName) < 0)
4522
if(snprintf(buf, sizeof(buf), "%s", CONST_DOMAIN_STATS_HTML) < 0)
4526
addPageIndicator(buf, pageNum, numEntries,
4527
myGlobals.maxNumLines,
4528
revertOrder, abs(sortedColumn));
4531
/* RRDs for domains */
4532
if (domainName != NULL) {
4533
struct stat statbufDomain;
4535
/* Do NOT add a '/' at the end of the path because Win32 will complain about it */
4536
if(snprintf(buf, sizeof(buf), "%s/interfaces/%s/domains/%s",
4537
myGlobals.rrdPath != NULL ? myGlobals.rrdPath : ".",
4538
myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName,domainName) < 0)
4541
if((i = stat(buf, &statbufDomain)) == 0) {
4542
if(snprintf(buf, sizeof(buf),
4544
"<center><table border=\"0\"><tr>"
4545
"<td valign=\"middle\" align=\"right\">Show domain-wide traffic charts:</td>\n"
4546
"<td align=\"right\">"
4548
"[ <a href=\"/" CONST_PLUGINS_HEADER
4549
"rrdPlugin?action=list&key=interfaces/%s/domains/%s&title=Domain%%20%s\">"
4550
"<img border=\"0\" src=\"/graph.gif\" alt=\"Domain-wide Historical Data\"></a> ]"
4553
"</tr></table>\n</center>\n"
4555
myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName,
4556
domainName,domainName) < 0)
4563
sendString("<p align=\"center\"><b>NOTE</b>: The domain is determined by simply stripping off "
4564
"the first name, so for host x.yz.com, the domain is yz.com and for host "
4565
"x.y.z.com, the domain is y.z.com</p>\n");
4567
free(tmpStats); free(stats);
4570
/* ************************* */
4572
void printNoDataYet(void) {
4573
printFlagedWarning("<I>No Data To Display (yet)</I>");
4576
/* ************************* */
4578
void printNotAvailable(char * flagName) {
4579
char buf[LEN_GENERAL_WORK_BUFFER];
4580
if(snprintf(buf, sizeof(buf), "<I>The requested data is not available when ntop is"
4581
"<br>started with the command line flag %s</I>",
4584
printFlagedWarning(buf);
4587
/* ************************* */
4589
void listNetFlows(void) {
4590
char buf[LEN_GENERAL_WORK_BUFFER];
4592
FlowFilterList *list = myGlobals.flowsList;
4593
char formatBuf[32], formatBuf1[32];
4595
printHTMLheader(NULL, NULL, 0);
4598
while(list != NULL) {
4599
if(list->pluginStatus.activePlugin) {
4600
if(numEntries == 0) {
4601
printPageTitle("Network Flows");
4602
sendString("<CENTER>\n");
4603
sendString(""TABLE_ON"<TABLE BORDER=1><TR "TR_ON" "DARK_BG"><TH "TH_BG">Flow Name</TH>"
4604
"<TH "TH_BG">Packets</TH><TH "TH_BG">Traffic</TH></TR>");
4607
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT "DARK_BG">%s</TH><TD "TD_BG" ALIGN=RIGHT>%s"
4608
"</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD></TR>\n",
4609
getRowColor(), list->flowName,
4610
formatPkts(list->packets.value, formatBuf, sizeof(formatBuf)),
4611
formatBytes(list->bytes.value, 1, formatBuf1, sizeof(formatBuf1))) < 0) BufferTooShort();
4621
sendString("</TABLE>"TABLE_OFF"\n");
4623
sendString("</CENTER>\n");
4626
if(numEntries == 0) {
4627
sendString("<CENTER><P><H1>No Available/Active Network Flows</H1><p>"
4628
" (see <A HREF=" CONST_MAN_NTOP_HTML ">man</A> page)</CENTER>\n");
4632
/* *********************************** */
4634
void printHostHourlyTraffic(HostTraffic *el) {
4635
Counter tcSent, tcRcvd;
4637
char theDate[8], macAddr[24];
4639
char buf[LEN_GENERAL_WORK_BUFFER], *targetStr;
4640
char hours[][24] = {"12 AM", "1 AM", "2 AM", "3 AM", "4 AM", "5 AM", "6 AM",
4641
"7 AM", "8 AM", "9 AM", "10 AM", "11 AM", "12 PM", "1 PM",
4642
"2 PM", "3 PM", "4 PM", "5 PM", "6 PM", "7 PM", "8 PM",
4643
"9 PM", "10 PM", "11 PM"};
4645
if(el->trafficDistribution == NULL) return;
4647
strftime(theDate, 8, CONST_TOD_HOUR_TIMESPEC, localtime_r(&myGlobals.actTime, &t));
4648
hourId = atoi(theDate);
4650
/* In FC, where traffic is mostly storage traffic, the word "host" has a
4651
* specific meaning (SCSI Initiator) and so we distinguish the title for
4654
if (isFcHost (el)) {
4655
printSectionTitle("FibreChannel Port Traffic Stats");
4658
printSectionTitle("Host Traffic Stats");
4661
sendString("<CENTER>\n");
4662
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\">\n<TR "DARK_BG">");
4663
sendString("<TH "TH_BG">Time</TH>");
4664
sendString("<TH "TH_BG">Tot. Traffic Sent</TH>");
4665
sendString("<TH "TH_BG">% Traffic Sent</TH>");
4666
sendString("<TH "TH_BG">Tot. Traffic Rcvd</TH>");
4667
sendString("<TH "TH_BG">% Traffic Rcvd</TH></TR>");
4669
for(i=0, tcSent=0, tcRcvd=0; i<24; i++) {
4670
tcSent += el->trafficDistribution->last24HoursBytesSent[i].value;
4671
tcRcvd += el->trafficDistribution->last24HoursBytesRcvd[i].value;
4674
for (i = 0, j = hourId; i < 24; i++) {
4676
if (snprintf (buf, sizeof (buf), "<TR><TH "TH_BG" ALIGN=RIGHT "DARK_BG">%s</TH>\n", hours[j]) < 0)
4679
printHostHourlyTrafficEntry(el, j, tcSent, tcRcvd);
4686
sendString("<TR><TH "TH_BG" "DARK_BG">Total</TH>\n");
4688
if (isFcHost (el)) {
4689
targetStr = el->hostNumFcAddress;
4692
if(snprintf(macAddr, sizeof(macAddr), "%s", el->ethAddressString) < 0)
4694
targetStr = el->hostNumIpAddress[0] == '\0' ? macAddr : el->hostNumIpAddress;
4697
urlFixupToRFC1945Inplace(targetStr);
4700
if(snprintf(buf, sizeof(buf), "<TD ALIGN=CENTER COLSPAN=2 "TD_BG" BGCOLOR=white>"
4701
"<IMG SRC=\"/hostTimeTrafficDistribution-%s"CHART_FORMAT"?1\""
4702
" alt=\"hostTraffic sent distribution chart\">"
4708
sendString("<TD COLSPAN=2 "TD_BG"> </TD>\n");
4711
if(snprintf(buf, sizeof(buf), "<TD ALIGN=CENTER COLSPAN=2 "TD_BG" BGCOLOR=white>"
4712
"<IMG SRC=\"/hostTimeTrafficDistribution-%s"CHART_FORMAT"\""
4713
" alt=\"hostTraffic rcvd distribution chart\">"
4719
sendString("<TD COLSPAN=2 "TD_BG"> </TD>\n");
4721
sendString("</TR>\n");
4723
sendString("</TABLE>"TABLE_OFF"\n</CENTER>\n");
4726
/* ************************** */
4728
static void dumpHostsCriteria(NtopInterface *ifName, u_char criteria) {
4729
u_int numEntries=0, i, maxHosts;
4730
HostTraffic **tmpTable, *el;
4731
char buf[LEN_GENERAL_WORK_BUFFER];
4732
float marcoRcvd = 0, marcoSent = 0;
4733
char formatBuf[32], formatBuf1[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
4735
maxHosts = ifName->hostsno; /* save it as it can change */
4737
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "dumpHostsCriteria");
4738
if(tmpTable == NULL)
4743
myGlobals.columnSort = 10;
4746
myGlobals.columnSort = 11;
4750
for(el=getFirstHost(myGlobals.actualReportDeviceId);
4751
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
4755
if(el->hostAS > 0) tmpTable[numEntries++] = el;
4758
if(el->vlanId > 0) tmpTable[numEntries++] = el;
4762
if(numEntries >= maxHosts)
4766
if(numEntries > 0) {
4768
Counter dataSent, dataRcvd;
4770
qsort(tmpTable, numEntries, sizeof(HostTraffic*), sortHostFctn);
4773
AS Data Sent/Rcvd patch courtesy of Marco Sanson <marco.sanson@infvic.it>
4776
if(snprintf(buf, sizeof(buf), "<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n"
4777
"<TR "TR_ON" "DARK_BG">"
4778
"<TH "TH_BG">%s</A></TH>\n"
4779
"<TH "TH_BG">Hosts</TH>\n"
4780
"<TH "TH_BG">Data Sent</TH>\n"
4781
"<TH "TH_BG">Data Rcvd</TH></TR>\n",
4782
criteria == 0 ? "AS" : "VLAN") < 0)
4786
dataSent = dataRcvd = 0;
4788
for(i=0; i<numEntries; i++) {
4789
el = tmpTable[numEntries-i-1];
4791
if(((criteria == 0) && (lastId == el->hostAS)) ||
4792
((criteria == 1) && (lastId == el->vlanId))) {
4793
/* Same AS or VLAN as last entry... just continue it */
4794
sendString("\n<br>");
4796
/* New AS or VLAN */
4799
/* Finish prior row */
4800
if(snprintf(buf, sizeof(buf),
4801
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n"
4802
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n"
4804
formatBytes(dataSent, 1, formatBuf, sizeof(formatBuf)),
4805
formatBytes(dataRcvd, 1, formatBuf1, sizeof(formatBuf1))) < 0)
4811
dataSent = dataRcvd = 0;
4813
sendString("<TR "TR_ON">\n");
4815
if(criteria == 0 /* AS */) {
4816
lastId = el->hostAS;
4817
if(snprintf(buf, sizeof(buf),
4818
"<TH "TH_BG" ALIGN=RIGHT "DARK_BG">"
4819
"<a href=\"" DEFAULT_AS_LOOKUP_URL "%d\" title=\"Lookup ASN (offsite)\">%d</a>"
4821
el->hostAS, el->hostAS) < 0)
4824
lastId = el->vlanId;
4825
if(snprintf(buf, sizeof(buf),
4826
"<TH "TH_BG" ALIGN=RIGHT>%d</TH>\n",
4832
sendString("<TH "TH_BG" ALIGN=LEFT>");
4836
sendString(makeHostLink(el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
4837
hostLinkBuf, sizeof(hostLinkBuf)));
4839
dataSent += el->bytesSent.value;
4840
dataRcvd += el->bytesRcvd.value;
4844
sendString("</TH>\n");
4846
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n"
4847
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
4848
formatBytes(dataSent, 1, formatBuf, sizeof(formatBuf)),
4849
formatBytes(dataRcvd, 1, formatBuf1, sizeof(formatBuf1))) < 0)
4854
sendString("</TR>\n</TABLE>\n</CENTER>");
4857
printFlagedWarning("<I>No entries to display(yet)</I>");
4863
/* ************************** */
4865
void printASList(unsigned int deviceId) {
4866
printHTMLheader("Autonomous Systems Traffic Statistics", NULL, 0);
4868
if(deviceId > myGlobals.numDevices) {
4869
printFlagedWarning("<I>Invalid device specified</I>");
4873
dumpHostsCriteria(&myGlobals.device[deviceId], 0 /* AS */);
4876
/* ******************************* */
4878
void printVLANList(unsigned int deviceId) {
4879
printHTMLheader("VLAN Traffic Statistics", NULL, 0);
4881
if(deviceId > myGlobals.numDevices) {
4882
printFlagedWarning("<I>Invalid device specified</I>");
4886
dumpHostsCriteria(&myGlobals.device[deviceId], 1 /* VLAN */);
4889
/* ******************************************* */
4891
static int recentlyUsedPort(HostTraffic *el, int portNr, int serverPort) {
4894
if(el == NULL) return(0);
4896
for(i=0; i<MAX_NUM_RECENT_PORTS; i++) {
4898
if(el->recentlyUsedServerPorts[i] == portNr)
4901
if(el->recentlyUsedClientPorts[i] == portNr)
4909
/* ******************************************* */
4911
void showPortTraffic(u_short portNr) {
4912
char buf[LEN_GENERAL_WORK_BUFFER], *str;
4913
int numRecords = 0, firstRun = 1;
4915
char portBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
4917
str = getAllPortByNum(portNr, portBuf, sizeof(portBuf));
4919
if((str[0] == '?') || (atoi(str) == portNr)) {
4920
if(snprintf(buf, sizeof(buf), "Recent Users of Port %u", portNr) < 0)
4923
if(snprintf(buf, sizeof(buf), "Recent Users of Port %u (%s)", portNr, str) < 0)
4927
printHTMLheader(buf, NULL, 0);
4928
sendString("<CENTER>\n");
4930
for(el=getFirstHost(myGlobals.actualReportDeviceId);
4931
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
4932
recentlyUsedPortSent:
4933
if(recentlyUsedPort(el, portNr, 0)) {
4934
if(numRecords == 0) {
4935
sendString("<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "DARK_BG"><TH>Client</TH><TH>Server</TH></TR>\n");
4936
sendString("<TR>\n<TD>\n");
4939
sendString("\n<LI> ");
4940
sendString(makeHostLink(el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)));
4944
if(el == myGlobals.broadcastEntry) break;
4949
el = myGlobals.broadcastEntry;
4950
goto recentlyUsedPortSent;
4955
if(numRecords > 0) {
4956
sendString("\n \n</TD><TD>\n");
4959
for(el=getFirstHost(myGlobals.actualReportDeviceId);
4960
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
4961
recentlyUsedPortRcvd:
4962
if(recentlyUsedPort(el, portNr, 1)) {
4963
if(numRecords == 0) {
4964
sendString("<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "DARK_BG"><TH>Client</TH><TH>Server</TH></TR>\n");
4965
sendString("<TR>\n<TD>\n");
4966
sendString("\n \n</TD><TD>\n");
4969
sendString("\n<LI> ");
4970
sendString(makeHostLink(el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)));
4974
if(el == myGlobals.broadcastEntry) break;
4980
el = myGlobals.broadcastEntry;
4981
goto recentlyUsedPortRcvd;
4984
if(numRecords == 0) {
4985
sendString("<P>No hosts found: the information for this port has been purged in the meantime</CENTER><P>\n");
4987
sendString("\n \n</TD>\n</TR>\n</TABLE>\n</CENTER>");
4991
/* ******************************************* */
4993
void printFcHostsTraffic(int reportType,
4998
LocalityDisplayPolicy showLocalityMode) {
4999
u_int idx, numEntries=0, maxHosts, whatToDo;
5000
int printedEntries=0, hourId;
5004
HostTraffic** tmpTable;
5005
char buf[LEN_GENERAL_WORK_BUFFER], formatBuf[8][32], vsanBuf[LEN_MEDIUM_WORK_BUFFER];
5006
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
5007
float sentPercent=0, rcvdPercent=0, totPercent=0;
5008
Counter totFcBytesSent=0, totFcBytesRcvd=0, totFcBytes=0;
5009
char *url0=NULL, *url1=NULL, *url2=NULL;
5011
memset(buf, 0, sizeof(buf));
5012
switch(reportType) {
5013
case SORT_FC_ACTIVITY:
5014
if(snprintf(buf, sizeof(buf), "FibreChannel Activity") < 0)
5018
if(snprintf(buf, sizeof(buf), "FibreChannel Traffic: ") < 0)
5022
if(snprintf(buf, sizeof(buf), "FibreChannel Throughput: ") < 0)
5026
if(snprintf(buf, sizeof(buf), "?? %d : ", reportType) < 0)
5031
if(reportType != SORT_FC_ACTIVITY) {
5032
switch(showLocalityMode) {
5033
case showSentReceived:
5034
strncat(buf, "Data Sent+Received", sizeof(buf) - strlen(buf) - 1);
5037
strncat(buf, "Data Sent", sizeof(buf) - strlen(buf) - 1);
5039
case showOnlyReceived:
5040
strncat(buf, "Data Received", sizeof(buf) - strlen(buf) - 1);
5044
printHTMLheader(buf, 0, 0);
5046
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
5048
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcHostsTraffic");
5049
if(tmpTable == NULL)
5052
strftime(theDate, 8, CONST_TOD_HOUR_TIMESPEC, localtime_r(&myGlobals.actTime, &t));
5053
hourId = atoi(theDate);
5055
for (el = getFirstHost (myGlobals.actualReportDeviceId);
5056
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
5057
if (isFcHost (el)) {
5058
/* Skip Control VSAN traffic */
5059
if (el->vsanId > MAX_USER_VSAN) continue;
5061
if (((showLocalityMode == showOnlySent) && (el->fcBytesSent.value > 0))
5062
|| ((showLocalityMode == showOnlyReceived) && (el->fcBytesRcvd.value > 0))
5063
|| ((showLocalityMode == showSentReceived) && ((el->fcBytesSent.value > 0) ||
5064
(el->fcBytesRcvd.value > 0)))) {
5065
tmpTable[numEntries++]=el;
5067
if (numEntries >= maxHosts)
5073
if(numEntries <= 0) {
5079
if(reportType != SORT_FC_ACTIVITY) {
5080
switch(showLocalityMode) {
5081
case showSentReceived:
5082
if(snprintf(buf, sizeof(buf), "<p align=\"right\">"
5083
"[<b> All </b>] "
5084
"[ <a href=\"%s?col=%s%d&showL=1\">Sent Only</a> ] "
5085
"[ <a href=\"%s?col=%s%d&showL=2\">Received Only</a> ] </p>",
5086
url, revertOrder ? "-" : "", sortedColumn, showLocalityMode,
5087
url, revertOrder ? "-" : "", sortedColumn, showLocalityMode) < 0)
5091
if(snprintf(buf, sizeof(buf), "<p align=\"right\">"
5092
"[ <a href=\"%s?col=%s%d&showH=%d&showL=0\">All</a> ] "
5093
"[<b> Sent Only </b>] "
5094
"[ <a href=\"%s?col=%s%d&showH=%d&showL=2\">Received Only</a> ] </p>",
5095
url, revertOrder ? "-" : "", sortedColumn, showLocalityMode,
5096
url, revertOrder ? "-" : "", sortedColumn, showLocalityMode) < 0)
5100
if(snprintf(buf, sizeof(buf), "<p align=\"right\">"
5101
"[ <a href=\"%s?col=%s%d&showH=%d&showL=0\">All</a> ] "
5102
"[ <a href=\"%s?col=%s%d&showH=%d&showL=1\">Sent Only</a> ] "
5103
"[<b> Received Only </b>] </p>",
5104
url, revertOrder ? "-" : "", sortedColumn, showLocalityMode,
5105
url, revertOrder ? "-" : "", sortedColumn, showLocalityMode) < 0)
5112
printFcHeader(reportType, revertOrder, abs(sortedColumn), hourId, url);
5114
myGlobals.columnSort = sortedColumn;
5117
traceEvent(CONST_TRACE_INFO, "FC_DEBUG: reportType=%d/sortedColumn=%d/myGlobals.columnSort=%d",
5118
reportType, sortedColumn, myGlobals.columnSort);
5121
myGlobals.reportKind = reportType;
5122
/* if(myGlobals.columnSort == 0) myGlobals.reportKind = 0;*/
5124
qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpFcFctn);
5126
totFcBytesSent = totFcBytesRcvd = totFcBytes = 0;
5128
for(idx=0; idx<numEntries; idx++) {
5129
if(tmpTable[idx] != NULL) {
5130
/* Count 'em both - not worth the IFs */
5131
totFcBytesSent += tmpTable[idx]->fcBytesSent.value;
5132
totFcBytesRcvd += tmpTable[idx]->fcBytesRcvd.value;
5133
switch(showLocalityMode) {
5134
case showSentReceived:
5135
totFcBytes += tmpTable[idx]->fcBytesSent.value +
5136
tmpTable[idx]->fcBytesRcvd.value;
5139
totFcBytes += tmpTable[idx]->fcBytesSent.value;
5141
case showOnlyReceived:
5142
totFcBytes += tmpTable[idx]->fcBytesRcvd.value;
5148
/* Avoid core dumps */
5149
if(totFcBytesSent == 0) totFcBytesSent = 1;
5150
if(totFcBytesRcvd == 0) totFcBytesRcvd = 1;
5151
if(totFcBytes == 0) totFcBytes = 1;
5154
traceEvent(CONST_TRACE_INFO, "FC_DEBUG: totIpBytesSent=%u, totIpBytesRcvd=%u totIpBytes=%u",
5155
totFcBytesSent, totFcBytesRcvd, totFcBytes);
5158
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
5159
char webHostName[LEN_GENERAL_WORK_BUFFER];
5162
el = tmpTable[numEntries-idx-1];
5167
sentPercent = (100*(float)el->fcBytesSent.value)/totFcBytesSent;
5168
rcvdPercent = (100*(float)el->fcBytesRcvd.value)/totFcBytesRcvd;
5169
totPercent = (100*(float) (el->fcBytesSent.value + el->fcBytesRcvd.value) )/totFcBytes;
5171
strncpy(webHostName,
5172
makeFcHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0,
5173
hostLinkBuf, sizeof (hostLinkBuf)),
5174
sizeof(webHostName));
5176
/* We have two reports x three data breakdowns + activity...
5177
cheat and create a number for a 1d switch() 100*Locality + SORT_FC
5178
precise formula is irrelevant, as long as it's unique...
5180
whatToDo = 100*showLocalityMode + reportType;
5183
case (100*showSentReceived + SORT_FC_DATA):
5184
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5186
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
5187
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5188
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5189
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>",
5191
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
5192
vsanBuf, sizeof (vsanBuf)),
5194
formatBytes(el->fcBytesSent.value +el->fcBytesRcvd.value, 1, formatBuf[1], 32),
5195
totPercent, myGlobals.separator,
5196
formatBytes(el->fcFcpBytesSent.value +el->fcFcpBytesRcvd.value, 1, formatBuf[2], 32),
5197
formatBytes(el->fcElsBytesSent.value +el->fcElsBytesRcvd.value, 1, formatBuf[3], 32),
5198
formatBytes(el->fcDnsBytesSent.value +el->fcDnsBytesRcvd.value, 1, formatBuf[4], 32),
5199
formatBytes(el->fcIpfcBytesSent.value +el->fcIpfcBytesRcvd.value, 1, formatBuf[5], 32),
5200
formatBytes(el->fcSwilsBytesSent.value+el->fcSwilsBytesRcvd.value, 1, formatBuf[6], 32),
5201
formatBytes(el->otherFcBytesSent.value+el->otherFcBytesRcvd.value, 1, formatBuf[7], 32)) < 0)
5204
case (100*showOnlySent + SORT_FC_DATA):
5205
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5207
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
5208
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5209
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5210
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>",
5212
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
5213
vsanBuf, sizeof (vsanBuf)),
5215
formatBytes(el->fcBytesSent.value, 1, formatBuf[1], 32),
5216
sentPercent, myGlobals.separator,
5217
formatBytes(el->fcFcpBytesSent.value, 1, formatBuf[2], 32),
5218
formatBytes(el->fcElsBytesSent.value, 1, formatBuf[3], 32),
5219
formatBytes(el->fcDnsBytesSent.value, 1, formatBuf[4], 32),
5220
formatBytes(el->fcIpfcBytesSent.value, 1, formatBuf[5], 32),
5221
formatBytes(el->fcSwilsBytesSent.value, 1, formatBuf[6], 32),
5222
formatBytes(el->otherFcBytesSent.value, 1, formatBuf[7], 32)) < 0)
5225
case (100*showOnlyReceived + SORT_FC_DATA):
5226
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5228
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
5229
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5230
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5231
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD>",
5233
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT, vsanBuf,
5236
formatBytes(el->fcBytesRcvd.value, 1, formatBuf[1], 32),
5237
rcvdPercent, myGlobals.separator,
5238
formatBytes(el->fcFcpBytesRcvd.value, 1, formatBuf[2], 32),
5239
formatBytes(el->fcElsBytesRcvd.value, 1, formatBuf[3], 32),
5240
formatBytes(el->fcDnsBytesRcvd.value, 1, formatBuf[4], 32),
5241
formatBytes(el->fcIpfcBytesRcvd.value, 1, formatBuf[5], 32),
5242
formatBytes(el->fcSwilsBytesRcvd.value, 1, formatBuf[6], 32),
5243
formatBytes(el->otherFcBytesRcvd.value, 1, formatBuf[7], 32)) < 0)
5246
case (100*showSentReceived + SORT_FC_THPT):
5247
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5249
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5250
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5251
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5252
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
5253
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
5254
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>",
5256
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
5257
vsanBuf, sizeof (vsanBuf)),
5259
formatThroughput(el->actualTThpt, 1, formatBuf[0], 32),
5260
formatThroughput(el->averageTThpt, 1, formatBuf[1], 32),
5261
formatThroughput(el->peakTThpt, 1, formatBuf[2], 32),
5263
el->averageTPktThpt,
5264
el->peakTPktThpt) < 0)
5267
case (100*showOnlySent + SORT_FC_THPT):
5268
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5270
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5271
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5272
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5273
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
5274
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
5275
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>",
5277
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
5278
vsanBuf, sizeof (vsanBuf)),
5280
formatThroughput(el->actualSentThpt, 1, formatBuf[0], 32),
5281
formatThroughput(el->averageSentThpt, 1, formatBuf[1], 32),
5282
formatThroughput(el->peakSentThpt, 1, formatBuf[2], 32),
5283
el->actualSentPktThpt,
5284
el->averageSentPktThpt,
5285
el->peakSentPktThpt) < 0)
5288
case (100*showOnlyReceived + SORT_FC_THPT):
5289
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5291
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5292
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5293
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5294
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
5295
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>"
5296
"<TD "TD_BG" ALIGN=RIGHT>%.1f Pkts/sec</TD>",
5298
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
5299
vsanBuf, sizeof (vsanBuf)),
5301
formatThroughput(el->actualRcvdThpt, 1, formatBuf[0], 32),
5302
formatThroughput(el->averageRcvdThpt, 1, formatBuf[1], 32),
5303
formatThroughput(el->peakRcvdThpt, 1, formatBuf[2], 32),
5304
el->actualRcvdPktThpt,
5305
el->averageRcvdPktThpt,
5306
el->peakRcvdPktThpt) < 0)
5309
case SORT_FC_ACTIVITY:
5310
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5313
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
5314
vsanBuf, sizeof (vsanBuf)),
5318
printHostThtpShort(el, reportType, hourId);
5323
sendString("</TR>\n");
5325
/* Avoid huge tables */
5326
if(printedEntries++ > myGlobals.maxNumLines)
5331
sendString("\n</TABLE>"TABLE_OFF"\n");
5333
switch(reportType) {
5336
case SORT_FC_ACTIVITY:
5339
sendString("<P><I>Note: These counters do not include broadcasts and "
5340
"will not equal the 'Global Protocol Distribution'</I></P>\n");
5344
sendString("</CENTER>\n");
5346
printFooter(reportType);
5348
addPageIndicator(url, pageNum, numEntries, myGlobals.maxNumLines,
5349
revertOrder, abs(sortedColumn));
5351
myGlobals.lastRefreshTime = myGlobals.actTime;
5355
/* ******************************* */
5357
void printFcHostsInfo(int sortedColumn, int revertOrder, int pageNum) {
5358
u_int idx, numEntries, maxHosts;
5359
int printedEntries=0, i;
5360
unsigned short maxBandwidthUsage=1 /* avoid divisions by zero */;
5361
struct hostTraffic *el;
5362
struct hostTraffic** tmpTable;
5363
char buf[2*LEN_GENERAL_WORK_BUFFER], *arrowGif, *sign, *arrow[12], *theAnchor[12];
5364
char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
5365
char htmlAnchor[64], htmlAnchor1[64], tmpbuf[LEN_FC_ADDRESS_DISPLAY];
5367
printHTMLheader("FibreChannel Hosts Information", 0, 0);
5369
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
5371
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcHostsInfo");
5372
if(tmpTable == NULL)
5375
memset(buf, 0, sizeof(buf));
5379
arrowGif = " " CONST_IMG_ARROW_UP;
5382
arrowGif = " " CONST_IMG_ARROW_DOWN;
5385
myGlobals.columnSort = sortedColumn;
5389
for(el=getFirstHost(myGlobals.actualReportDeviceId);
5390
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
5391
unsigned short actUsage;
5393
if (!isFcHost (el) || (el->vsanId > MAX_USER_VSAN)) continue;
5395
if ((el->hostNumFcAddress[0] != '\0') &&
5396
el->fcBytesSent.value) {
5397
actUsage = (unsigned short)(100*((float)el->fcBytesSent.value/
5398
(float)myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value));
5399
el->actBandwidthUsage = actUsage;
5400
if(el->actBandwidthUsage > maxBandwidthUsage)
5401
maxBandwidthUsage = actUsage;
5403
tmpTable[numEntries++]=el;
5405
if(numEntries >= maxHosts)
5410
if(numEntries <= 0) {
5416
qsort(tmpTable, numEntries, sizeof(struct hostTraffic*), sortHostFctn);
5418
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s",
5419
CONST_FC_HOSTS_INFO_HTML, sign) < 0)
5421
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=",
5422
CONST_FC_HOSTS_INFO_HTML) < 0)
5425
for(i=1; i<=9; i++) {
5426
if(abs(myGlobals.columnSort) == i) {
5427
arrow[i] = arrowGif;
5428
theAnchor[i] = htmlAnchor;
5431
theAnchor[i] = htmlAnchor1;
5435
if(abs(myGlobals.columnSort) == FLAG_DOMAIN_DUMMY_IDX) {
5436
arrow[0] = arrowGif;
5437
theAnchor[0] = htmlAnchor;
5440
theAnchor[0] = htmlAnchor1;
5443
if (snprintf(buf, sizeof(buf), "<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON">"
5444
"<TH "TH_BG" "DARK_BG">%s3>VSAN%s</A></TH>"
5445
"<TH "TH_BG" "DARK_BG">%s1>FC_Port%s</A></TH>"
5446
"</TH><TH "TH_BG" "DARK_BG">%s2>FC Address%s</A></TH>\n"
5447
"<TH "TH_BG" "DARK_BG">%s4>Sent Bandwidth%s</A></TH>"
5448
"<TH "TH_BG" "DARK_BG">Nw Board Vendor</TH>"
5449
"<TH "TH_BG" "DARK_BG">%s9>Age%s</A></TH>"
5451
theAnchor[3], arrow[3],
5452
theAnchor[1], arrow[1],
5453
theAnchor[2], arrow[2],
5454
theAnchor[4], arrow[4],
5455
theAnchor[9], arrow[9]
5461
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
5463
el = tmpTable[numEntries-idx-1];
5468
char *tmpName1, *tmpName2;
5470
strncpy (tmpbuf, fc_to_str ((u_int8_t *)&el->hostFcAddress),
5471
LEN_FC_ADDRESS_DISPLAY);
5474
if((tmpName1[0] == '\0') || (strcmp(tmpName1, "0.0.0.0") == 0))
5475
tmpName1 = myGlobals.separator;
5477
tmpName2 = getVendorInfo (&el->pWWN.str[2], 0);
5478
if (tmpName2[0] == '\0') {
5482
traceEvent(CONST_TRACE_INFO, "FC_DEBUG: %s <=> %s [%s/%s]",
5483
el->hostNumIpAddress, sniffedName,
5484
el->hostResolvedName, el->hostNumIpAddress);
5487
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>", getRowColor()) < 0)
5491
if (snprintf (buf, sizeof (buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
5492
makeVsanLink (el->vsanId, 0,
5493
vsanBuf, sizeof (vsanBuf))) < 0)
5497
sendString(makeFcHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0,
5498
hostLinkBuf, sizeof (hostLinkBuf)));
5500
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
5505
printBar(buf, sizeof(buf), el->actBandwidthUsageS, el->actBandwidthUsageR, maxBandwidthUsage, 3);
5507
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>", tmpName2) < 0)
5511
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</A></TD>",
5512
formatSeconds(el->lastSeen - el->firstSeen,
5513
formatBuf, sizeof (formatBuf))) < 0)
5517
sendString("</TR>\n");
5520
/* Avoid huge tables */
5521
if(printedEntries > myGlobals.maxNumLines)
5524
traceEvent(CONST_TRACE_WARNING, "quicksort() problem!");
5527
sendString("</TABLE>"TABLE_OFF"<P>\n");
5528
sendString("</CENTER>\n");
5530
printFooterHostLink();
5532
printBandwidthFooter();
5534
addPageIndicator(CONST_HOSTS_INFO_HTML, pageNum, numEntries,
5535
myGlobals.maxNumLines, revertOrder, abs(sortedColumn));
5540
/* ************************************ */
5542
void printFcAccounting(int remoteToLocal, int sortedColumn,
5543
int revertOrder, int pageNum) {
5544
u_int idx, numEntries = 0, maxHosts, i;
5545
int printedEntries=0;
5546
HostTraffic *el, **tmpTable;
5547
char buf[LEN_GENERAL_WORK_BUFFER], *sign;
5548
char tmpbuf[LEN_WWN_ADDRESS_DISPLAY+1];
5549
char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[2][32];
5550
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
5551
Counter totalBytesSent, totalBytesRcvd, totalBytes, a=0, b=0;
5552
float sentpct, rcvdpct;
5553
time_t timeDiff = time(NULL)-myGlobals.initialSniffTime;
5554
char *arrowGif, *arrow[8], *theAnchor[8];
5555
char htmlAnchor[64], htmlAnchor1[64];
5557
printHTMLheader("FibreChannel Per Port Traffic", 0, 0);
5559
maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
5561
tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcAccounting");
5562
if(tmpTable == NULL)
5567
arrowGif = " " CONST_IMG_ARROW_UP;
5570
arrowGif = " " CONST_IMG_ARROW_DOWN;
5573
totalBytesSent=0, totalBytesRcvd=0;
5575
for(el=getFirstHost(myGlobals.actualReportDeviceId);
5576
el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
5577
if (!isFcHost (el)) continue;
5579
/* Skip Control VSAN traffic */
5580
if (el->vsanId > MAX_USER_VSAN) continue;
5582
if((el->fcBytesSent.value > 0) || (el->fcBytesRcvd.value > 0)) {
5583
tmpTable[numEntries++]=el;
5584
totalBytesSent += el->fcBytesSent.value;
5585
totalBytesRcvd += el->fcBytesRcvd.value;
5587
if(numEntries >= maxHosts) break;
5590
if(numEntries <= 0) {
5596
myGlobals.columnSort = sortedColumn;
5597
qsort(tmpTable, numEntries, sizeof(struct hostTraffic*), cmpHostsFctn);
5599
if(snprintf(htmlAnchor, sizeof(htmlAnchor),
5600
"<a href=\"" CONST_FC_TRAFFIC_HTML "?col=%s", sign) < 0)
5602
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
5603
"<a href=\"" CONST_FC_TRAFFIC_HTML "?col=") < 0)
5606
for (i = 1; i < 6; i++) {
5607
if (abs (myGlobals.columnSort) == i) {
5608
arrow[i] = arrowGif;
5609
theAnchor[i] = htmlAnchor;
5613
theAnchor[i] = htmlAnchor1;
5616
sendString("<CENTER>\n");
5617
if(snprintf(buf, sizeof(buf), ""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON">"
5618
"<TH "TH_BG" "DARK_BG">%s5\">VSAN%s</a></TH>"
5619
"<TH "TH_BG" "DARK_BG">%s1\">FC_Port%s</a></TH>"
5620
"<TH "TH_BG" "DARK_BG">%s2\">FC_ID%s</a></TH>\n"
5621
"<TH "TH_BG" COLSPAN=2 "DARK_BG">%s3\">Bytes Sent%s</a></TH>"
5622
"<TH "TH_BG" COLSPAN=2 "DARK_BG">%s4\">Bytes Rcvd%s</a></TH></TR>\n",
5623
theAnchor[5], arrow[5],
5624
theAnchor[1], arrow[1],
5625
theAnchor[2], arrow[2], theAnchor[3], arrow[3],
5626
theAnchor[4], arrow[4]) < 0)
5631
for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
5634
el = tmpTable[numEntries-idx-1];
5640
strncpy (tmpbuf, (char *)el->hostNumFcAddress,
5641
LEN_FC_ADDRESS_DISPLAY);
5644
a = el->fcBytesSent.value;
5645
b = el->fcBytesRcvd.value;
5647
if(a < 100) /* Avoid very small decimal values */
5650
sentpct = (100*(float)a)/totalBytesSent;
5652
if(b < 100) /* Avoid very small decimal values */
5655
rcvdpct = (100*(float)b)/totalBytesRcvd;
5657
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5659
"%s<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5660
"</TD><TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD>"
5661
"<TD "TD_BG" ALIGN=RIGHT>%s</TD><TD "TD_BG" ALIGN=RIGHT>%.1f%s%%</TD></TR>\n",
5663
makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
5664
vsanBuf, sizeof (vsanBuf)),
5665
makeFcHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0,
5666
hostLinkBuf, sizeof (hostLinkBuf)),
5668
formatBytes(a, 1, formatBuf[0], 32),
5669
sentpct, myGlobals.separator,
5670
formatBytes(b, 1, formatBuf[1], 32),
5671
rcvdpct, myGlobals.separator) < 0)
5675
/* Avoid huge tables */
5676
if(printedEntries++ > myGlobals.maxNumLines)
5681
sendString("</TABLE>"TABLE_OFF"\n");
5683
addPageIndicator(CONST_FC_TRAFFIC_HTML, pageNum, numEntries, myGlobals.maxNumLines,
5684
revertOrder, abs(sortedColumn));
5686
sendString("<P><CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n<TR "TR_ON">"
5687
"<TH "TH_BG" ALIGN=RIGHT "DARK_BG">Total Traffic</TH>"
5688
"<TH "TH_BG" ALIGN=RIGHT "DARK_BG">Used Bandwidth</TH></TR>\n");
5690
totalBytes = totalBytesSent+totalBytesRcvd;
5692
if(snprintf(buf, sizeof(buf), "<TR "TR_ON">"
5693
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5694
"<TD "TD_BG" ALIGN=RIGHT>%s</TD></TR>\n",
5695
formatBytes(totalBytes, 1, formatBuf[0], 32),
5696
formatThroughput((float)(totalBytes/timeDiff), 1,
5697
formatBuf[1], 32)) < 0)
5701
sendString("</TABLE>"TABLE_OFF"\n");
5702
sendString("</CENTER>\n");
5704
printFooterHostLink();
5709
/* ********************************** */
5711
int printScsiSessionBytes (int actualDeviceId, int sortedColumn, int revertOrder,
5712
int pageNum, char *url, HostTraffic *el) {
5714
int numSessions, printedSessions, skipSessions;
5715
ScsiSessionSortEntry *tmpTable, *entry;
5717
char buf[LEN_GENERAL_WORK_BUFFER*2], *sign, *title=NULL;
5718
char *arrowGif, *arrow[48], *theAnchor[48];
5719
char htmlAnchor[64], htmlAnchor1[64];
5720
char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[7][32];
5721
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER],
5722
hostLinkBuf1[LEN_GENERAL_WORK_BUFFER];
5725
printHTMLheader("SCSI Sessions: Bytes", 0, 0);
5727
if(!myGlobals.enableSessionHandling) {
5728
printNotAvailable("-z or --disable-sessions");
5732
/* We have to allocate as many entries as there are sessions and LUNs
5735
tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
5736
if (tmpTable == NULL) {
5737
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n");
5741
memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
5743
for(i=strlen(url); i>0; i--)
5749
urlFixupToRFC1945Inplace(url);
5751
#ifdef CFG_MULTITHREADED
5752
accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionBytes");
5755
/* Let's count sessions first */
5756
for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) {
5757
session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx];
5758
while (session != NULL) {
5760
if (session->magic != CONST_MAGIC_NUMBER) {
5761
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n");
5764
if (session->fcpBytesSent.value || session->fcpBytesRcvd.value) {
5765
if ((el && ((session->initiator == el)
5766
|| (session->remotePeer == el)))
5768
for (j = 0; j < MAX_LUNS_SUPPORTED; j++) {
5769
if (session->activeLuns[j] != NULL) {
5770
if ((session->activeLuns[j]->invalidLun &&
5771
!myGlobals.noInvalidLunDisplay) ||
5772
(!session->activeLuns[j]->invalidLun)) {
5773
tmpTable[numSessions].initiator = session->initiator;
5774
tmpTable[numSessions].target = session->remotePeer;
5775
tmpTable[numSessions].lun = j;
5776
tmpTable[numSessions++].stats = session->activeLuns[j];
5778
if (j > session->lunMax)
5782
if ((session->unknownLunBytesSent.value ||
5783
session->unknownLunBytesRcvd.value)) {
5784
if ((el && ((session->initiator == el)
5785
|| (session->remotePeer == el)))
5787
tmpTable[numSessions].initiator = session->initiator;
5788
tmpTable[numSessions].target = session->remotePeer;
5789
tmpTable[numSessions].lun = 0xFFFF;
5790
tmpTable[numSessions++].stats = (ScsiLunTrafficInfo *)session;
5795
session = session->next;
5799
if(numSessions > 0) {
5803
arrowGif = " " CONST_IMG_ARROW_UP;
5806
arrowGif = " " CONST_IMG_ARROW_DOWN;
5809
myGlobals.columnSort = sortedColumn;
5810
qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
5813
if (strcmp (url, CONST_SCSI_BYTES_HTML) == 0) {
5814
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
5816
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
5818
if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
5822
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
5824
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
5826
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
5831
/* Need to add info about page in Hosts Info mode */
5832
if(snprintf(htmlAnchor, sizeof(htmlAnchor),
5833
"<A HREF=/%s.html?showF=%d&page=%d&col=%s", url,
5834
showHostScsiSessionBytes, pageNum, sign) < 0)
5836
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
5837
"<A HREF=/%s.html?showF=%d&page=%d&col=", url,
5838
showHostScsiSessionBytes, pageNum) < 0)
5840
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
5841
url, showHostScsiSessionBytes) < 0)
5845
for (i = 1; i < 48; i++) {
5847
if(abs(myGlobals.columnSort) == i) {
5848
arrow[i] = arrowGif;
5849
theAnchor[i] = htmlAnchor;
5852
theAnchor[i] = htmlAnchor1;
5857
#ifdef CFG_MULTITHREADED
5858
releaseMutex(&myGlobals.fcSessionsMutex);
5865
#ifdef CFG_MULTITHREADED
5866
releaseMutex(&myGlobals.fcSessionsMutex);
5870
Due to the way sessions are handled, sessions before those to
5871
display need to be skipped
5873
printedSessions = 0;
5875
for (idx = 0; idx < numSessions; idx++) {
5876
Counter dataSent, dataRcvd;
5879
entry = &tmpTable[numSessions-idx-1];
5881
entry = &tmpTable[idx];
5883
if (entry == NULL) {
5887
if (printedSessions < myGlobals.maxNumLines) {
5890
&& (entry->initiator != el)
5891
&& (entry->target != el)) {
5895
if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
5899
if(printedSessions == 0) {
5900
sendString("<CENTER>\n");
5901
if (snprintf(buf, sizeof (buf),
5902
""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\"><TR "TR_ON">"
5903
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s1>VSAN%s</A></TH>"
5904
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s2>Initiator%s</A></TH>"
5905
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s3>Target%s</A></TH>"
5906
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">LUN</TH>"
5907
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Total Bytes</TH>"
5908
"<TH "TH_BG" "DARK_BG" COLSPAN=3>Data Bytes</TH>"
5909
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Rd Size(Blks)</TH>"
5910
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Wr Size(Blks)</TH>"
5911
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Xfer Rdy Size</TH>"
5912
"<TH "TH_BG" "DARK_BG" COLSPAN=2>IOPS</TH>"
5914
theAnchor[1], arrow[1],
5915
theAnchor[2], arrow[2],
5916
theAnchor[3], arrow[3]
5917
) < 0) BufferTooShort ();
5920
if (snprintf(buf, sizeof (buf),
5922
"<TH "TH_BG" "DARK_BG">%s4>Sent%s</A></TH>"
5923
"<TH "TH_BG" "DARK_BG">%s5>Rcvd%s</A></TH>"
5924
"<TH "TH_BG" "DARK_BG">%s6>Read%s</A></TH>"
5925
"<TH "TH_BG" "DARK_BG">%s7>Write%s</A></TH>"
5926
"<TH "TH_BG" "DARK_BG">%s8>Other%s</A></TH>"
5927
"<TH "TH_BG" "DARK_BG">%s9>Min%s</A></TH>"
5928
"<TH "TH_BG" "DARK_BG">%s10>Max%s</A></TH>"
5929
"<TH "TH_BG" "DARK_BG">%s11>Min%s</A></TH>"
5930
"<TH "TH_BG" "DARK_BG">%s12>Max%s</A></TH>"
5931
"<TH "TH_BG" "DARK_BG">%s13>Min%s</A></TH>"
5932
"<TH "TH_BG" "DARK_BG">%s14>Max%s</A></TH>"
5933
"<TH "TH_BG" "DARK_BG">%s15>Min%s</A></TH>"
5934
"<TH "TH_BG" "DARK_BG">%s16>Max%s</A></TH>"
5937
theAnchor[4], arrow[4],
5938
theAnchor[5], arrow[5],
5939
theAnchor[6], arrow[6],
5940
theAnchor[7], arrow[7],
5941
theAnchor[8], arrow[8],
5942
theAnchor[9], arrow[9],
5943
theAnchor[10], arrow[10],
5944
theAnchor[11], arrow[11],
5945
theAnchor[12], arrow[12],
5946
theAnchor[13], arrow[13],
5947
theAnchor[14], arrow[14],
5948
theAnchor[15], arrow[15],
5949
theAnchor[16], arrow[16]
5957
if (entry->lun != 0xFFFF) {
5958
dataSent = entry->stats->bytesSent.value;
5959
dataRcvd = entry->stats->bytesRcvd.value;
5962
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
5963
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5964
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5965
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5966
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
5967
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5968
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5969
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5970
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5971
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5972
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
5973
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
5974
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
5975
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
5976
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5977
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
5978
"<TD "TD_BG" ALIGN=RIGHT>%.1f</TD>"
5979
"<TD "TD_BG" ALIGN=RIGHT>%.1f</TD>"
5982
makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
5984
makeFcHostLink(entry->initiator,
5985
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
5986
hostLinkBuf, sizeof (hostLinkBuf)),
5987
makeFcHostLink(entry->target,
5988
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
5989
hostLinkBuf1, sizeof (hostLinkBuf1)),
5991
formatBytes(dataSent, 1, formatBuf[0], 32),
5992
formatBytes(dataRcvd, 1, formatBuf[1], 32),
5993
formatBytes (entry->stats->scsiRdBytes.value, 1,
5995
formatBytes (entry->stats->scsiWrBytes.value, 1,
5997
formatBytes (entry->stats->scsiOtBytes.value, 1,
5999
entry->stats->minRdSize,
6000
entry->stats->maxRdSize,
6001
entry->stats->minWrSize,
6002
entry->stats->maxWrSize,
6003
formatBytes (entry->stats->minXferRdySize, 1,
6005
formatBytes (entry->stats->maxXferRdySize, 1,
6007
entry->stats->minIops,
6008
entry->stats->maxIops
6009
) < 0) BufferTooShort();
6012
/* Unknown LUN data */
6013
session = (FCSession *)entry->stats;
6016
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
6017
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6018
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6019
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6020
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6021
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6022
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6023
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6024
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6025
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6026
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6027
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6028
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6029
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6030
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6031
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6032
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6033
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6036
makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
6038
makeFcHostLink(entry->initiator,
6039
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6040
hostLinkBuf, sizeof (hostLinkBuf)),
6041
makeFcHostLink(entry->target,
6042
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6043
hostLinkBuf1, sizeof (hostLinkBuf1)),
6045
formatBytes(session->unknownLunBytesSent.value, 1,
6047
formatBytes(session->unknownLunBytesRcvd.value, 1,
6060
) < 0) BufferTooShort();
6068
if (printedSessions > 0) {
6069
sendString("</TABLE>"TABLE_OFF"<P>\n");
6070
sendString("</CENTER>\n");
6071
sendString("<P><I>Note: Entries with LUN as N/A indicate traffic for which no command frame was seen</I></P>\n");
6072
addPageIndicator(pageUrl, pageNum, numSessions-1, myGlobals.maxNumLines,
6073
revertOrder, sortedColumn);
6075
printFooterHostLink();
6078
printFlagedWarning("<I>No SCSI Sessions</I>");
6083
return (printedSessions);
6086
/* ********************************** */
6088
int printScsiSessionTimes (int actualDeviceId, int sortedColumn, int revertOrder,
6089
int pageNum, char *url, HostTraffic *el) {
6091
int numSessions, printedSessions, skipSessions;
6092
unsigned long duration;
6093
ScsiSessionSortEntry *tmpTable, *entry;
6095
char buf[LEN_GENERAL_WORK_BUFFER], *sign, *title=NULL;
6096
char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[10][32];
6097
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER],
6098
hostLinkBuf1[LEN_GENERAL_WORK_BUFFER];
6099
char *arrowGif, *arrow[48], *theAnchor[48];
6100
char htmlAnchor[64], htmlAnchor1[64], pageUrl[64];
6102
printHTMLheader("SCSI Sessions: Times", 0, 0);
6104
if(!myGlobals.enableSessionHandling) {
6105
printNotAvailable("-z or --disable-sessions");
6109
/* We have to allocate as many entries as there are sessions and LUNs
6112
tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
6113
if (tmpTable == NULL) {
6114
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n");
6118
memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
6120
for(i=strlen(url); i>0; i--)
6126
urlFixupFromRFC1945Inplace(url);
6128
#ifdef CFG_MULTITHREADED
6129
accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionTimes");
6132
/* Let's count sessions first */
6133
for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) {
6134
session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx];
6135
while (session != NULL) {
6136
if (session->magic != CONST_MAGIC_NUMBER) {
6137
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n");
6140
if (session->fcpBytesSent.value || session->fcpBytesRcvd.value) {
6141
if ((el && ((session->initiator == el)
6142
|| (session->remotePeer == el)))
6144
for (j = 0; j < MAX_LUNS_SUPPORTED; j++) {
6145
if (session->activeLuns[j] != NULL) {
6146
if ((session->activeLuns[j]->invalidLun &&
6147
!myGlobals.noInvalidLunDisplay) ||
6148
(!session->activeLuns[j]->invalidLun)) {
6149
tmpTable[numSessions].initiator = session->initiator;
6150
tmpTable[numSessions].target = session->remotePeer;
6151
tmpTable[numSessions].lun = j;
6152
tmpTable[numSessions++].stats = session->activeLuns[j];
6154
if (j > session->lunMax)
6158
/* Don't care about unknown LUN info as we don't gather
6159
* anything but bytes for such traffic.
6163
session = session->next;
6167
if(numSessions > 0) {
6171
arrowGif = " " CONST_IMG_ARROW_UP;
6174
arrowGif = " " CONST_IMG_ARROW_DOWN;
6177
myGlobals.columnSort = sortedColumn;
6178
qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
6181
if (strcmp (url, CONST_SCSI_TIMES_HTML) == 0) {
6182
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
6184
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
6186
if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
6190
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
6192
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
6194
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
6199
/* Need to add info about page in Hosts Info mode */
6200
if(snprintf(htmlAnchor, sizeof(htmlAnchor),
6201
"<A HREF=/%s.html?showF=%d&page=%d&col=%s", url,
6202
showHostScsiSessionTimes, pageNum, sign) < 0)
6204
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
6205
"<A HREF=/%s.html?showF=%d&page=%d&col=", url,
6206
showHostScsiSessionTimes, pageNum) < 0)
6208
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
6209
url, showHostScsiSessionTimes) < 0)
6213
for (i = 1; i < 48; i++) {
6214
if(abs(myGlobals.columnSort) == i) {
6215
arrow[i] = arrowGif;
6216
theAnchor[i] = htmlAnchor;
6219
theAnchor[i] = htmlAnchor1;
6224
#ifdef CFG_MULTITHREADED
6225
releaseMutex(&myGlobals.fcSessionsMutex);
6232
#ifdef CFG_MULTITHREADED
6233
releaseMutex(&myGlobals.fcSessionsMutex);
6236
Due to the way sessions are handled, sessions before those to
6237
display need to be skipped
6239
printedSessions = skipSessions = 0;
6240
for (idx = 0; idx < numSessions; idx++) {
6243
entry = &tmpTable[numSessions-idx-1];
6245
entry = &tmpTable[idx];
6247
if (entry == NULL) {
6251
if (printedSessions < myGlobals.maxNumLines) {
6254
&& (entry->initiator != el)
6255
&& (entry->target != el)) {
6259
if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
6263
if(printedSessions == 0) {
6264
sendString("<CENTER>\n");
6266
if (snprintf(buf, sizeof (buf),
6267
""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\"><TR "TR_ON">"
6268
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s1>VSAN%s</A></TH>"
6269
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s2>Initiator%s</A></TH>"
6270
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s3>Target%s</A></TH>"
6271
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">LUN</TH>"
6272
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Cmd-Status RTT</TH>"
6273
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Cmd-XFR_RDY RTT</TH>"
6274
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Cmd-Data RTT(Rd)</TH>"
6275
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Cmd-Data RTT(Wr)</TH>"
6276
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s26>Active Since%s</A></TH>"
6277
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s27>Last Seen%s</A></TH>"
6279
theAnchor[1], arrow[1],
6280
theAnchor[2], arrow[2],
6281
theAnchor[3], arrow[3],
6282
theAnchor[26], arrow[26],
6283
theAnchor[27], arrow[27]
6284
) < 0) BufferTooShort ();
6287
if (snprintf(buf, sizeof (buf),
6289
"<TH "TH_BG" "DARK_BG">%s18>Min%s</A></TH>"
6290
"<TH "TH_BG" "DARK_BG">%s19>Max%s</A></TH>"
6291
"<TH "TH_BG" "DARK_BG">%s20>Min%s</A></TH>"
6292
"<TH "TH_BG" "DARK_BG">%s21>Max%s</A></TH>"
6293
"<TH "TH_BG" "DARK_BG">%s22>Min%s</A></TH>"
6294
"<TH "TH_BG" "DARK_BG">%s23>Max%s</A></TH>"
6295
"<TH "TH_BG" "DARK_BG">%s24>Min%s</A></TH>"
6296
"<TH "TH_BG" "DARK_BG">%s25>Max%s</A></TH>"
6299
theAnchor[18], arrow[18],
6300
theAnchor[19], arrow[19],
6301
theAnchor[20], arrow[20],
6302
theAnchor[21], arrow[21],
6303
theAnchor[22], arrow[22],
6304
theAnchor[23], arrow[23],
6305
theAnchor[24], arrow[24],
6306
theAnchor[25], arrow[25]
6315
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
6316
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6317
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6318
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6319
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6320
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6321
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6322
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6323
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6324
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6325
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6326
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6327
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6328
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6329
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6332
makeVsanLink (entry->initiator->vsanId, 0,
6333
vsanBuf, sizeof (vsanBuf)),
6334
makeFcHostLink(entry->initiator,
6335
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6336
hostLinkBuf, sizeof (hostLinkBuf)),
6337
makeFcHostLink(entry->target,
6338
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6339
hostLinkBuf1, sizeof (hostLinkBuf1)),
6341
formatLatency (entry->stats->minRTT, FLAG_STATE_ACTIVE,
6342
formatBuf[0], sizeof(formatBuf[0])),
6343
formatLatency (entry->stats->maxRTT, FLAG_STATE_ACTIVE,
6344
formatBuf[1], sizeof(formatBuf[1])),
6345
formatLatency (entry->stats->minXfrRdyRTT, FLAG_STATE_ACTIVE,
6346
formatBuf[2], sizeof(formatBuf[2])),
6347
formatLatency (entry->stats->maxXfrRdyRTT, FLAG_STATE_ACTIVE,
6348
formatBuf[3], sizeof(formatBuf[3])),
6349
formatLatency (entry->stats->minRdFrstDataRTT, FLAG_STATE_ACTIVE,
6350
formatBuf[4], sizeof(formatBuf[4])),
6351
formatLatency (entry->stats->maxRdFrstDataRTT, FLAG_STATE_ACTIVE,
6352
formatBuf[5], sizeof(formatBuf[5])),
6353
formatLatency (entry->stats->minWrFrstDataRTT, FLAG_STATE_ACTIVE,
6354
formatBuf[6], sizeof(formatBuf[6])),
6355
formatLatency (entry->stats->maxWrFrstDataRTT, FLAG_STATE_ACTIVE,
6356
formatBuf[7], sizeof(formatBuf[7])),
6357
formatTime((time_t *)&(entry->stats->firstSeen),
6358
formatBuf[8], sizeof(formatBuf[8])),
6359
formatTime((time_t *)&(entry->stats->lastSeen),
6360
formatBuf[9], sizeof(formatBuf[9]))
6361
) < 0) BufferTooShort();
6368
if (printedSessions > 0) {
6369
sendString("</TABLE>"TABLE_OFF"<P>\n");
6370
sendString("</CENTER>\n");
6372
addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.maxNumLines,
6373
revertOrder, sortedColumn);
6375
printFooterHostLink();
6378
printFlagedWarning("<I>No SCSI Sessions</I>");
6383
return (printedSessions);
6386
/* ********************************** */
6388
int printScsiSessionStatusInfo (int actualDeviceId, int sortedColumn,
6389
int revertOrder, int pageNum, char *url,
6392
int numSessions, printedSessions, skipSessions;
6393
ScsiSessionSortEntry *tmpTable, *entry;
6395
char buf[LEN_GENERAL_WORK_BUFFER], *sign, *title=NULL;
6396
char *arrowGif, *arrow[48], *theAnchor[48];
6397
char htmlAnchor[64], htmlAnchor1[64], pageUrl[64];
6398
char vsanBuf[LEN_MEDIUM_WORK_BUFFER];
6399
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER],
6400
hostLinkBuf1[LEN_GENERAL_WORK_BUFFER];
6402
printHTMLheader("SCSI Sessions: Status Info", 0, 0);
6404
if(!myGlobals.enableSessionHandling) {
6405
printNotAvailable("-z or --disable-sessions");
6409
/* We have to allocate as many entries as there are sessions and LUNs
6412
tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
6413
if (tmpTable == NULL) {
6414
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n");
6418
memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
6420
for(i=strlen(url); i>0; i--)
6426
urlFixupFromRFC1945Inplace(url);
6428
#ifdef CFG_MULTITHREADED
6429
accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionStatusInfo");
6431
/* Let's count sessions first */
6432
for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) {
6433
session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx];
6434
while (session != NULL) {
6435
if (session->magic != CONST_MAGIC_NUMBER) {
6436
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n");
6439
if (session->fcpBytesSent.value || session->fcpBytesRcvd.value) {
6440
if ((el && ((session->initiator == el)
6441
|| (session->remotePeer == el)))
6443
for (j = 0; j < MAX_LUNS_SUPPORTED; j++) {
6444
if (session->activeLuns[j] != NULL) {
6445
if ((session->activeLuns[j]->invalidLun &&
6446
!myGlobals.noInvalidLunDisplay) ||
6447
(!session->activeLuns[j]->invalidLun)) {
6448
tmpTable[numSessions].initiator = session->initiator;
6449
tmpTable[numSessions].target = session->remotePeer;
6450
tmpTable[numSessions].lun = j;
6451
tmpTable[numSessions++].stats = session->activeLuns[j];
6453
if (j > session->lunMax)
6459
session = session->next;
6463
if(numSessions > 0) {
6467
arrowGif = " " CONST_IMG_ARROW_UP;
6470
arrowGif = " " CONST_IMG_ARROW_DOWN;
6473
myGlobals.columnSort = sortedColumn;
6474
qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
6477
if (strcmp (url, CONST_SCSI_STATUS_HTML) == 0) {
6478
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
6480
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
6482
if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
6486
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
6488
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
6490
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
6495
/* Need to add info about page in Hosts Info mode */
6496
if(snprintf(htmlAnchor, sizeof(htmlAnchor),
6497
"<A HREF=/%s.html?showF=%d&page=%d&col=%s", url,
6498
showHostScsiSessionStatus, pageNum, sign) < 0)
6500
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
6501
"<A HREF=/%s.html?showF=%d&page=%d&col=", url,
6502
showHostScsiSessionStatus, pageNum) < 0)
6504
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
6505
url, showHostScsiSessionStatus) < 0)
6509
for (i = 1; i < 48; i++) {
6510
if(abs(myGlobals.columnSort) == i) {
6511
arrow[i] = arrowGif;
6512
theAnchor[i] = htmlAnchor;
6515
theAnchor[i] = htmlAnchor1;
6520
#ifdef CFG_MULTITHREADED
6521
releaseMutex(&myGlobals.fcSessionsMutex);
6527
#ifdef CFG_MULTITHREADED
6528
releaseMutex(&myGlobals.fcSessionsMutex);
6531
Due to the way sessions are handled, sessions before those to
6532
display need to be skipped
6534
printedSessions = skipSessions = 0;
6535
for (idx = 0; idx < numSessions; idx++) {
6538
entry = &tmpTable[numSessions-idx-1];
6540
entry = &tmpTable[idx];
6542
if (entry == NULL) {
6546
if (printedSessions < myGlobals.maxNumLines) {
6549
&& (entry->initiator != el)
6550
&& (entry->target != el)) {
6554
if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
6558
if(printedSessions == 0) {
6559
sendString("<CENTER>\n");
6560
if (snprintf(buf, sizeof (buf),
6561
""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\"><TR "TR_ON">"
6562
"<TH "TH_BG" "DARK_BG">%s1>VSAN%s</A></TH>"
6563
"<TH "TH_BG" "DARK_BG">%s2>Initiator%s</A></TH>"
6564
"<TH "TH_BG" "DARK_BG">%s3>Target%s</A></TH>"
6565
"<TH "TH_BG" "DARK_BG">LUN</TH>"
6566
"<TH "TH_BG" "DARK_BG">%s17># Failed Cmds%s</A></TH>"
6567
"<TH "TH_BG" "DARK_BG">%s28># Check Condition%s</A></TH>"
6568
"<TH "TH_BG" "DARK_BG">%s29># Busy%s</A></TH>"
6569
"<TH "TH_BG" "DARK_BG">%s30># Reservation Conflict%s</A></TH>"
6570
"<TH "TH_BG" "DARK_BG">%s31># Task Set Full%s</A></TH>"
6571
"<TH "TH_BG" "DARK_BG">%s32># Task Aborts%s</A></TH>"
6573
theAnchor[1], arrow[1],
6574
theAnchor[2], arrow[2],
6575
theAnchor[3], arrow[3],
6576
theAnchor[17], arrow[17],
6577
theAnchor[28], arrow[28],
6578
theAnchor[29], arrow[29],
6579
theAnchor[30], arrow[30],
6580
theAnchor[31], arrow[31],
6581
theAnchor[32], arrow[32]
6582
) < 0) BufferTooShort ();
6587
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
6588
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6589
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6590
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6591
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6592
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6593
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6594
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6595
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6596
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6597
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6600
makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
6602
makeFcHostLink(entry->initiator,
6603
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6604
hostLinkBuf, sizeof (hostLinkBuf)),
6605
makeFcHostLink(entry->target,
6606
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6607
hostLinkBuf1, sizeof (hostLinkBuf1)),
6609
entry->stats->numFailedCmds,
6610
entry->stats->chkCondCnt,
6611
entry->stats->busyCnt,
6612
entry->stats->resvConflictCnt,
6613
entry->stats->taskSetFullCnt,
6614
entry->stats->taskAbrtCnt
6615
) < 0) BufferTooShort();
6622
if (printedSessions > 0) {
6623
sendString("</TABLE>"TABLE_OFF"<P>\n");
6624
sendString("</CENTER>\n");
6626
addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.maxNumLines,
6627
revertOrder, sortedColumn);
6629
printFooterHostLink();
6632
printFlagedWarning("<I>No SCSI Sessions</I>");
6637
return (printedSessions);
6640
int printScsiSessionTmInfo (int actualDeviceId, int sortedColumn,
6641
int revertOrder, int pageNum, char *url,
6645
int numSessions, printedSessions, skipSessions, total;
6646
ScsiSessionSortEntry *tmpTable, *entry;
6648
char buf[LEN_GENERAL_WORK_BUFFER], *sign, *title=NULL;
6649
char *arrowGif, *arrow[48], *theAnchor[48];
6650
char htmlAnchor[64], htmlAnchor1[64], pageUrl[64];
6651
char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[2][32];
6652
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER],
6653
hostLinkBuf1[LEN_GENERAL_WORK_BUFFER];
6655
printHTMLheader("SCSI Sessions: Task Management Info", 0, 0);
6657
if(!myGlobals.enableSessionHandling) {
6658
printNotAvailable("-z or --disable-sessions");
6662
/* We have to allocate as many entries as there are sessions and LUNs
6665
tmpTable = (ScsiSessionSortEntry *) malloc (myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
6666
if (tmpTable == NULL) {
6667
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Unable to malloc sorting table\n");
6671
memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
6673
for(i=strlen(url); i>0; i--)
6679
urlFixupFromRFC1945Inplace(url);
6681
#ifdef CFG_MULTITHREADED
6682
accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionTmInfo");
6684
/* Let's count sessions first */
6685
for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) {
6686
session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx];
6687
while (session != NULL) {
6688
if (session->magic != CONST_MAGIC_NUMBER) {
6689
traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n");
6693
if ((session->fcpBytesRcvd.value) || (session->fcpBytesSent.value)) {
6694
if ((el && ((session->initiator == el)
6695
|| (session->remotePeer == el)))
6697
for (j = 0; j < MAX_LUNS_SUPPORTED; j++) {
6698
if (session->activeLuns[j] != NULL) {
6699
if ((session->activeLuns[j]->invalidLun &&
6700
!myGlobals.noInvalidLunDisplay) ||
6701
(!session->activeLuns[j]->invalidLun)) {
6702
tmpTable[numSessions].initiator = session->initiator;
6703
tmpTable[numSessions].target = session->remotePeer;
6704
tmpTable[numSessions].lun = j;
6705
tmpTable[numSessions++].stats = session->activeLuns[j];
6707
if (j > session->lunMax)
6713
session = session->next;
6717
if(numSessions > 0) {
6721
arrowGif = " " CONST_IMG_ARROW_UP;
6724
arrowGif = " " CONST_IMG_ARROW_DOWN;
6727
myGlobals.columnSort = sortedColumn;
6728
qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
6731
if (strcmp (url, CONST_SCSI_TM_HTML) == 0) {
6732
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
6734
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
6736
if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
6740
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
6742
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
6744
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
6749
/* Need to add info about page in Hosts Info mode */
6750
if(snprintf(htmlAnchor, sizeof(htmlAnchor),
6751
"<A HREF=/%s.html?showF=%d&page=%d&col=%s", url,
6752
showHostScsiSessionTMInfo, pageNum, sign) < 0)
6754
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
6755
"<A HREF=/%s.html?showF=%d&page=%d&col=", url,
6756
showHostScsiSessionTMInfo, pageNum) < 0)
6758
if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
6759
url, showHostScsiSessionTMInfo) < 0)
6763
for (i = 1; i < 48; i++) {
6764
if(abs(myGlobals.columnSort) == i) {
6765
arrow[i] = arrowGif;
6766
theAnchor[i] = htmlAnchor;
6769
theAnchor[i] = htmlAnchor1;
6774
#ifdef CFG_MULTITHREADED
6775
releaseMutex(&myGlobals.fcSessionsMutex);
6782
#ifdef CFG_MULTITHREADED
6783
releaseMutex(&myGlobals.fcSessionsMutex);
6786
Due to the way sessions are handled, sessions before those to
6787
display need to be skipped
6789
printedSessions = skipSessions = 0;
6790
for (idx = 0; idx < numSessions; idx++) {
6793
entry = &tmpTable[numSessions-idx-1];
6795
entry = &tmpTable[idx];
6797
if (entry == NULL) {
6801
if (printedSessions < myGlobals.maxNumLines) {
6804
&& (entry->initiator != el)
6805
&& (entry->target != el)) {
6809
if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
6813
if(printedSessions == 0) {
6814
sendString("<CENTER>\n");
6815
if (snprintf(buf, sizeof (buf),
6816
""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\"><TR "TR_ON">"
6817
"<TH "TH_BG" "DARK_BG">%s1>VSAN%s</A></TH>"
6818
"<TH "TH_BG" "DARK_BG">%s2>Initiator%s</A></TH>"
6819
"<TH "TH_BG" "DARK_BG">%s3>Target%s</A></TH>"
6820
"<TH "TH_BG" "DARK_BG">LUN</TH>"
6821
"<TH "TH_BG" "DARK_BG">%s33># Abort Task Set%s</A></TH>"
6822
"<TH "TH_BG" "DARK_BG">%s34># Clear Task Set%s</A></TH>"
6823
"<TH "TH_BG" "DARK_BG">%s35># Clear ACA%s</A></TH>"
6824
"<TH "TH_BG" "DARK_BG">%s36># Target Reset%s</A></TH>"
6825
"<TH "TH_BG" "DARK_BG">%s37># LUN Reset%s</A></TH>"
6826
"<TH "TH_BG" "DARK_BG">%s38>Last Target Reset Time%s</A></TH>"
6827
"<TH "TH_BG" "DARK_BG">%s39>Last LUN Reset Time%s</A></TH>"
6829
theAnchor[1], arrow[1],
6830
theAnchor[2], arrow[2],
6831
theAnchor[3], arrow[3],
6832
theAnchor[33], arrow[33],
6833
theAnchor[34], arrow[34],
6834
theAnchor[35], arrow[35],
6835
theAnchor[36], arrow[36],
6836
theAnchor[37], arrow[37],
6837
theAnchor[38], arrow[38],
6838
theAnchor[39], arrow[39]
6839
) < 0) BufferTooShort ();
6844
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
6845
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6846
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6847
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6848
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6849
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6850
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6851
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6852
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6853
"<TD "TD_BG" ALIGN=RIGHT>%d</TD>"
6854
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6855
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
6858
makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
6860
makeFcHostLink(entry->initiator,
6861
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6862
hostLinkBuf, sizeof (hostLinkBuf)),
6863
makeFcHostLink(entry->target,
6864
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
6865
hostLinkBuf1, sizeof (hostLinkBuf1)),
6867
entry->stats->abrtTaskSetCnt,
6868
entry->stats->clearTaskSetCnt,
6869
entry->stats->clearAcaCnt,
6870
entry->stats->tgtRstCnt,
6871
entry->stats->lunRstCnt,
6872
formatTime((time_t *)&(entry->stats->lastTgtRstTime),
6874
formatTime((time_t *)&(entry->stats->lastLunRstTime),
6876
) < 0) BufferTooShort();
6883
if (printedSessions > 0) {
6884
sendString("</TABLE>"TABLE_OFF"<P>\n");
6885
sendString("</CENTER>\n");
6887
addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.maxNumLines,
6888
revertOrder, sortedColumn);
6890
printFooterHostLink();
6893
printFlagedWarning("<I>No SCSI Sessions</I>");
6898
return (printedSessions);
6901
/* ********************************** */
6903
void printFCSessions (int actualDeviceId, int sortedColumn, int revertOrder,
6904
int pageNum, char *url, HostTraffic *el) {
6906
int numSessions, printedSessions, skipSessions;
6907
unsigned long duration;
6908
char buf[LEN_GENERAL_WORK_BUFFER], *sign, *title=NULL;
6909
char *arrowGif, *arrow[48], *theAnchor[48];
6910
char htmlAnchor[64], htmlAnchor1[64];
6911
char vsanBuf[LEN_MEDIUM_WORK_BUFFER], formatBuf[7][32];
6912
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER],
6913
hostLinkBuf1[LEN_GENERAL_WORK_BUFFER];
6914
FCSession **tmpTable, *session;
6916
printHTMLheader("FibreChannel Sessions", 0, 0);
6918
if(!myGlobals.enableSessionHandling) {
6919
printNotAvailable("-z or --disable-sessions");
6923
tmpTable = (FCSession**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numFcSessions*sizeof(FCSession *), "printFCSessions");
6924
if(tmpTable == NULL)
6927
for(i=strlen(url); i>0; i--)
6933
urlFixupFromRFC1945Inplace(url);
6936
Due to the way sessions are handled, sessions before those to
6937
display need to be skipped
6940
#ifdef CFG_MULTITHREADED
6941
accessMutex(&myGlobals.fcSessionsMutex, "printFCSessions");
6943
/* Let's count sessions first */
6944
for (idx=1, numSessions=0; idx < MAX_TOT_NUM_SESSIONS; idx++) {
6945
session = myGlobals.device[myGlobals.actualReportDeviceId].fcSession[idx];
6946
while (session != NULL) {
6947
if ((session->bytesSent.value || session->bytesRcvd.value) &&
6948
(session->initiator->vsanId < MAX_USER_VSAN)) {
6950
&& ((session->initiator == el)
6951
|| (session->remotePeer == el)))
6953
tmpTable[numSessions++] = session;
6956
session = session->next;
6960
#ifdef CFG_MULTITHREADED
6961
releaseMutex(&myGlobals.fcSessionsMutex);
6964
if(numSessions <= 0) {
6971
arrowGif = " " CONST_IMG_ARROW_UP;
6974
arrowGif = " " CONST_IMG_ARROW_DOWN;
6977
myGlobals.columnSort = sortedColumn;
6978
qsort (tmpTable, numSessions, sizeof (FCSession **), cmpFcSessionsFctn);
6980
if (strcmp (url, CONST_FC_SESSIONS_HTML) == 0) {
6981
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
6983
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
6986
if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
6988
if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
6992
for (i = 1; i < 21; i++) {
6993
if (abs(myGlobals.columnSort) == i) {
6994
arrow[i] = arrowGif;
6995
theAnchor[i] = htmlAnchor;
6999
theAnchor[i] = htmlAnchor1;
7003
printedSessions = skipSessions = 0;
7004
for (idx = 0; idx < numSessions; idx++) {
7005
Counter dataSent, dataRcvd;
7008
session = tmpTable[numSessions-idx-1];
7010
session = tmpTable[idx];
7012
if (session == NULL) {
7013
/* Some update is in progress ? */
7017
if (printedSessions < myGlobals.maxNumLines) {
7020
&& (session->initiator != el)
7021
&& (session->remotePeer != el)) {
7025
if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
7029
if(printedSessions == 0) {
7030
sendString("<CENTER>\n");
7031
if (snprintf (buf, sizeof (buf),
7032
""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"100%\"><TR "TR_ON">"
7033
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s1>VSAN%s</A></TH>\n"
7034
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s2>Sender%s</A></TH>\n"
7035
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s3>Receiver%s</A></TH>\n"
7036
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Total</TH>\n"
7037
"<TH "TH_BG" "DARK_BG" COLSPAN=2>SCSI</TH>\n"
7038
"<TH "TH_BG" "DARK_BG" COLSPAN=2>ELS</TH>\n"
7039
"<TH "TH_BG" "DARK_BG" COLSPAN=2>NS</TH>\n"
7040
"<TH "TH_BG" "DARK_BG" COLSPAN=2>IP/FC</TH>\n"
7041
"<TH "TH_BG" "DARK_BG" COLSPAN=2>SWILS</TH>\n"
7042
"<TH "TH_BG" "DARK_BG" COLSPAN=2>Others</TH>\n"
7043
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s18>Active Since%s</A></TH>\n"
7044
"<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s19>Last Seen%s</A></TH>"
7046
theAnchor[1], arrow[1],
7047
theAnchor[2], arrow[2],
7048
theAnchor[3], arrow[3],
7049
theAnchor[18], arrow[18],
7050
theAnchor[19], arrow[19]
7056
if (snprintf (buf, sizeof (buf),
7058
"<TH "TH_BG" "DARK_BG">%s4>Sent%s</A></TH>\n"
7059
"<TH "TH_BG" "DARK_BG">%s5>Rcvd%s</A></TH>\n"
7060
"<TH "TH_BG" "DARK_BG">%s6>Sent%s</A></TH>\n"
7061
"<TH "TH_BG" "DARK_BG">%s7>Rcvd%s</A></TH>\n"
7062
"<TH "TH_BG" "DARK_BG">%s8>Sent%s</A></TH>\n"
7063
"<TH "TH_BG" "DARK_BG">%s9>Rcvd%s</A></TH>\n"
7064
"<TH "TH_BG" "DARK_BG">%s10>Sent%s</A></TH>\n"
7065
"<TH "TH_BG" "DARK_BG">%s11>Rcvd%s</A></TH>\n",
7066
theAnchor[4], arrow[4],
7067
theAnchor[5], arrow[5],
7068
theAnchor[6], arrow[6],
7069
theAnchor[7], arrow[7],
7070
theAnchor[8], arrow[8],
7071
theAnchor[9], arrow[9],
7072
theAnchor[10], arrow[10],
7073
theAnchor[11], arrow[11]
7078
if (snprintf (buf, sizeof (buf),
7079
"<TH "TH_BG" "DARK_BG">%s12>Sent%s</A></TH>\n"
7080
"<TH "TH_BG" "DARK_BG">%s13>Rcvd%s</A></TH>\n"
7081
"<TH "TH_BG" "DARK_BG">%s14>Sent%s</A></TH>\n"
7082
"<TH "TH_BG" "DARK_BG">%s15>Rcvd%s</A></TH>\n"
7083
"<TH "TH_BG" "DARK_BG">%s16>Sent%s</A></TH>\n"
7084
"<TH "TH_BG" "DARK_BG">%s17>Rcvd%s</A></TH>"
7086
theAnchor[12], arrow[12],
7087
theAnchor[13], arrow[13],
7088
theAnchor[14], arrow[14],
7089
theAnchor[15], arrow[15],
7090
theAnchor[16], arrow[16],
7091
theAnchor[17], arrow[17]
7097
dataSent = session->bytesSent.value;
7098
dataRcvd = session->bytesRcvd.value;
7099
duration = session->lastSeen.tv_sec - session->firstSeen.tv_sec;
7102
if (snprintf (buf, sizeof(buf), "<TR "TR_ON" %s>"
7103
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7104
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7105
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7106
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7107
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7108
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7109
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7110
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7111
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7112
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7113
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7114
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7115
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7116
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7117
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7118
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7119
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7120
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7121
"<TD "TD_BG" ALIGN=RIGHT>%s</TD>"
7124
makeVsanLink (session->initiator->vsanId, 0,
7125
vsanBuf, sizeof (vsanBuf)),
7126
makeFcHostLink(session->initiator,
7127
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
7128
hostLinkBuf, sizeof (hostLinkBuf)),
7129
makeFcHostLink(session->remotePeer,
7130
FLAG_HOSTLINK_TEXT_FORMAT, 0, 0,
7131
hostLinkBuf1, sizeof (hostLinkBuf1)),
7132
formatBytes(dataSent, 1, formatBuf[0], 32),
7133
formatBytes(dataRcvd, 1, formatBuf[1], 32),
7134
formatBytes(session->fcpBytesSent.value, 1,
7136
formatBytes(session->fcpBytesRcvd.value, 1,
7138
formatBytes(session->fcElsBytesSent.value, 1,
7140
formatBytes(session->fcElsBytesRcvd.value, 1,
7142
formatBytes(session->fcDnsBytesSent.value, 1,
7144
formatBytes(session->fcDnsBytesRcvd.value, 1,
7146
formatBytes(session->ipfcBytesSent.value, 1,
7148
formatBytes(session->ipfcBytesRcvd.value, 1,
7150
formatBytes(session->fcSwilsBytesSent.value, 1,
7152
formatBytes(session->fcSwilsBytesRcvd.value, 1,
7154
formatBytes(session->otherBytesSent.value, 1,
7156
formatBytes(session->otherBytesRcvd.value, 1,
7158
formatTime((time_t *)&(session->firstSeen),
7160
formatTime((time_t *)&(session->lastSeen),
7162
) < 0) BufferTooShort();
7169
if (printedSessions > 0) {
7170
sendString("</TABLE>"TABLE_OFF"<P>\n");
7171
sendString("</CENTER>\n");
7173
addPageIndicator(url, pageNum, numSessions, myGlobals.maxNumLines,
7174
revertOrder, sortedColumn);
7176
printFooterHostLink();
7179
printFlagedWarning("<I>No FibreChannel Sessions</I>");
7186
/* ********************************** */
7188
void printFcProtocolDistribution(int mode, int revertOrder)
7190
char buf[2*LEN_GENERAL_WORK_BUFFER], *sign;
7191
float total, partialTotal, remainingTraffic;
7199
total = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value;
7205
int numProtosFound = 0;
7207
printSectionTitle("Global FibreChannel Protocol Distribution");
7209
sendString("<CENTER>\n");
7210
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=500><TR "TR_ON"><TH "TH_BG" "DARK_BG" WIDTH=150>"
7211
"FC Protocol</TH>"
7212
"<TH "TH_BG" WIDTH=50 "DARK_BG">Total Bytes</TH><TH "TH_BG" WIDTH=250 COLSPAN=2 "DARK_BG">"
7213
"Percentage</TH></TR>\n");
7215
remainingTraffic = 0;
7217
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcFcpBytes.value;
7218
if(partialTotal > 0) {
7219
remainingTraffic += partialTotal;
7220
percentage = ((float)(partialTotal*100))/((float)total);
7222
printTableEntry(buf, sizeof(buf), "SCSI",
7223
CONST_COLOR_1, partialTotal/1024, percentage);
7226
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcFiconBytes.value;
7227
if(partialTotal > 0) {
7228
remainingTraffic += partialTotal;
7229
percentage = ((float)(partialTotal*100))/((float)total);
7231
printTableEntry(buf, sizeof(buf), "FICON",
7232
CONST_COLOR_1, partialTotal/1024, percentage);
7235
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcElsBytes.value;
7236
if(partialTotal > 0) {
7237
remainingTraffic += partialTotal;
7238
percentage = ((float)(partialTotal*100))/((float)total);
7240
printTableEntry(buf, sizeof(buf), "ELS",
7241
CONST_COLOR_1, partialTotal/1024, percentage);
7244
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcDnsBytes.value;
7245
if(partialTotal > 0) {
7246
remainingTraffic += partialTotal;
7247
percentage = ((float)(partialTotal*100))/((float)total);
7249
printTableEntry(buf, sizeof(buf), "NS",
7250
CONST_COLOR_1, partialTotal/1024, percentage);
7254
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcIpfcBytes.value;
7255
if(partialTotal > 0) {
7256
remainingTraffic += partialTotal;
7257
percentage = ((float)(partialTotal*100))/((float)total);
7259
printTableEntry(buf, sizeof(buf), "IP/FC",
7260
CONST_COLOR_1, partialTotal/1024, percentage);
7263
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcSwilsBytes.value;
7264
if(partialTotal > 0) {
7265
remainingTraffic += partialTotal;
7266
percentage = ((float)(partialTotal*100))/((float)total);
7268
printTableEntry(buf, sizeof(buf), "SWILS",
7269
CONST_COLOR_1, partialTotal/1024, percentage);
7272
partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].otherFcBytes.value;
7273
if(partialTotal > 0) {
7274
remainingTraffic += partialTotal;
7275
percentage = ((float)(partialTotal*100))/((float)total);
7277
printTableEntry(buf, sizeof(buf), "Others",
7278
CONST_COLOR_1, partialTotal/1024, percentage);
7281
if(numProtosFound > 0)
7282
sendString("<TR "TR_ON"><TD "TD_BG" COLSPAN=4 ALIGN=CENTER BGCOLOR=white>"
7283
"<IMG SRC=\"" CONST_BAR_FC_PROTO_DIST CHART_FORMAT "\" "
7284
"alt=\"Global FC protocol distribution chart\"></TD></TR>\n");
7285
sendString("</TABLE>"TABLE_OFF"<P>\n");
7287
/* *********************** */
7289
sendString("<p>Note:This report includes broadcast packets</p>\n");
7290
sendString("</CENTER>\n");
7294
/* ************************ */
7297
void printFcTrafficMatrix (u_short vsanId, u_char sent)
7299
int i, j, numEntries=0, numConsecutiveEmptyCells;
7300
char buf[LEN_GENERAL_WORK_BUFFER];
7302
Counter minTraffic=(Counter)LONG_MAX, maxTraffic=0, avgTraffic;
7303
Counter avgTrafficLow, avgTrafficHigh, tmpCounter;
7304
TrafficEntry *entry;
7306
if(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix == NULL) {
7307
printFlagedWarning("<I>Traffic matrix is not available for the selected network interface</I>");
7311
/* Print a matrix, using just what the row/column header says: From -> To */
7312
/* This is different from IP which prints a total */
7314
if(snprintf (buf, sizeof(buf), "FibreChannel Traffic Matrix For VSAN %d", vsanId) < 0)
7318
if(snprintf (buf, sizeof(buf), "FibreChannel Traffic Matrix For VSAN") < 0)
7322
printHTMLheader(buf, 0);
7324
activeHosts = (short*)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numHosts*sizeof(short), "printFcTrafficMatrix");
7325
if(activeHosts == NULL)
7328
for(i=1; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; i++) {
7331
for(j=1; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; j++) {
7334
id = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
7335
entry = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[id];
7337
if ((i == j) && (myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i] != NULL) &&
7338
(strncmp (myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i]->hostNumFcAddress,
7339
"ff.ff.fd", sizeof ("ff.ff.fd")) != 0)) {
7341
else if ((entry != NULL) && (entry->vsanId == vsanId)) {
7342
if ((entry->bytesSent.value) || (entry->bytesRcvd.value)) {
7350
/* Print column header if there is traffic sent from another host to this
7353
if(activeHosts[i] == 1) {
7354
if(numEntries == 1) {
7355
sendString("<CENTER>\n");
7357
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON"><TH "TH_BG" ALIGN=LEFT><SMALL> F "
7358
" To<br> r<br> o<br> m</SMALL></TH>\n");
7360
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON"><TH "TH_BG" ALIGN=LEFT><SMALL> B "
7361
" From<br> y<br></SMALL></TH>\n");
7364
if(snprintf(buf, sizeof(buf), "<TH "TH_BG" ALIGN=CENTER><SMALL>%s</SMALL></TH>",
7365
getHostName(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i], 1)) < 0)
7371
if(numEntries == 0) {
7376
sendString("</TR>\n");
7378
/* Determine Min & Max values */
7379
for(i=1; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; i++) {
7380
for(j=1; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; j++) {
7381
int idx = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
7382
entry = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx];
7384
if ((entry != NULL) && (entry->vsanId == vsanId)) {
7385
if (sent && entry->bytesSent.value) {
7386
if(minTraffic > entry->bytesSent.value)
7387
minTraffic = entry->bytesSent.value;
7388
if(maxTraffic < entry->bytesSent.value)
7389
maxTraffic = entry->bytesSent.value;
7391
else if (!sent && entry->bytesRcvd.value) {
7392
if(minTraffic > entry->bytesRcvd.value)
7393
minTraffic = entry->bytesRcvd.value;
7394
if(maxTraffic < entry->bytesRcvd.value)
7395
maxTraffic = entry->bytesRcvd.value;
7401
avgTraffic = (Counter)(((float)minTraffic+(float)maxTraffic)/2);
7402
avgTrafficLow = (avgTraffic*15)/100; /* 15% of the average */
7403
avgTrafficHigh = 2*(maxTraffic/3); /* 75% of max traffic */
7407
for(i=1; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; i++)
7408
if(activeHosts[i] == 1) {
7409
numConsecutiveEmptyCells=0;
7411
if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT><SMALL>%s</SMALL></TH>",
7412
getRowColor(), makeFcHostLink(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i],
7413
FLAG_HOSTLINK_TEXT_FORMAT, 1, 1)) < 0)
7417
for(j=1; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; j++) {
7418
int idx = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
7421
(strncmp (myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i]->hostNumFcAddress,
7422
"ff.ff.fd", sizeof ("ff.ff.fd")) != 0)) {
7423
numConsecutiveEmptyCells++;
7425
else if (activeHosts[j] == 1) {
7426
if(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx] == NULL)
7427
numConsecutiveEmptyCells++;
7429
if(numConsecutiveEmptyCells > 0) {
7430
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d> </TD>\n",
7431
numConsecutiveEmptyCells) < 0) BufferTooShort();
7433
numConsecutiveEmptyCells = 0;
7437
tmpCounter = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx]->bytesSent.value;
7440
tmpCounter = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx]->bytesRcvd.value;
7442
/* Fix below courtesy of Danijel Doriae <danijel.doric@industrogradnja.tel.hr> */
7443
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER %s>"
7444
"<SMALL>%s</SMALL></A></TH>\n",
7445
calculateCellColor(tmpCounter, avgTrafficLow, avgTrafficHigh),
7446
formatBytes(tmpCounter, 1)) < 0)
7453
if(numConsecutiveEmptyCells > 0) {
7454
if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d> </TD>\n",
7455
numConsecutiveEmptyCells) < 0)
7458
numConsecutiveEmptyCells = 0;
7461
sendString("</TR>\n");
7464
sendString("</TABLE>"TABLE_OFF"\n<P>\n");
7465
sendString("</CENTER>\n");
7467
printFooterHostLink();
7473
/* ******************************************* */
7475
void printVSANList(unsigned int deviceId) {
7476
printHTMLheader("VSAN Traffic Statistics", 0, 0);
7478
if(deviceId > myGlobals.numDevices) {
7479
printFlagedWarning("<I>Invalid device specified</I>");
7481
} else if(myGlobals.device[deviceId].vsanHash == NULL) {
7482
printFlagedWarning("<I>No VSAN Traffic Information Available (yet).</I>");
7486
dumpFcFabricElementHash(myGlobals.device[deviceId].vsanHash, "VSAN", 0, 1);
7489
/* ********************************** */
7491
void drawVsanStatsGraph (unsigned int deviceId)
7493
char buf[LEN_GENERAL_WORK_BUFFER], vsanBuf[LEN_MEDIUM_WORK_BUFFER];
7494
FcFabricElementHash **theHash;
7495
FcFabricElementHash *tmpTable[MAX_ELEMENT_HASH];
7497
char vsanLabel[LEN_GENERAL_WORK_BUFFER];
7499
if(deviceId > myGlobals.numDevices) {
7500
printFlagedWarning("<I>Invalid device specified</I>");
7502
} else if ((theHash = myGlobals.device[deviceId].vsanHash) == NULL) {
7503
printHTMLheader("VSAN Summary", 0, 0);
7508
printHTMLheader("Top 10 VSANs", 0, 0);
7511
memset (tmpTable, sizeof (FcFabricElementHash *)*MAX_ELEMENT_HASH, 0);
7513
for (i=0; i<MAX_ELEMENT_HASH; i++) {
7514
if((theHash[i] != NULL) && (theHash[i]->vsanId < MAX_HASHDUMP_ENTRY) &&
7515
(theHash[i]->vsanId < MAX_USER_VSAN)) {
7516
if (theHash[i]->totBytes.value)
7517
tmpTable[numVsans++] = theHash[i];
7521
myGlobals.columnSort = 3;
7522
qsort (tmpTable, numVsans, sizeof (FcFabricElementHash **), cmpVsanFctn);
7524
sendString("<CENTER>\n");
7525
sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=600><TR "TR_ON"><TH "TH_BG" "DARK_BG" WIDTH=25>"
7527
"<TH "TH_BG" "DARK_BG" WIDTH=75>Total Bytes</TH><TH "TH_BG" "DARK_BG" WIDTH=500 COLSPAN=2>"
7528
"Percentage</TH></TR>\n");
7531
for (i = numVsans-1, j = 0; i >= 0; i--, j++) {
7532
if (tmpTable[i] != NULL) {
7533
if(snprintf (vsanLabel, sizeof (vsanLabel), "%s",
7534
makeVsanLink (tmpTable[i]->vsanId, 0, vsanBuf, sizeof (vsanBuf))) < 0)
7536
printTableEntry (buf, sizeof (buf), vsanLabel, CONST_COLOR_1,
7537
(float) tmpTable[i]->totBytes.value/1024,
7538
100*((float)SD(tmpTable[i]->totBytes.value,
7539
myGlobals.device[deviceId].fcBytes.value)));
7543
if (j >= MAX_VSANS_GRAPHED)
7546
sendString("</TABLE>"TABLE_OFF"<P>\n");
7548
printSectionTitle ("VSAN Traffic (Bytes)");
7549
if(snprintf(buf, sizeof(buf),
7550
"<TR "TR_ON" BGCOLOR=white><TH BGCOLOR=white ALIGN=CENTER COLSPAN=3>"
7551
"<IMG SRC=drawVsanStatsBytesDistribution"CHART_FORMAT"?1 ALT=\"VSAN Bytes Statistics "
7552
"VSAN Traffic (Total Bytes)\"></TH></TR>" ) < 0)
7556
printSectionTitle ("VSAN Traffic (Frames)");
7557
if(snprintf(buf, sizeof(buf),
7558
"<TR "TR_ON" BGCOLOR=white><TH BGCOLOR=white ALIGN=CENTER COLSPAN=3>"
7559
"<IMG SRC=drawVsanStatsPktsDistribution"CHART_FORMAT"?1 ALT=\"VSAN Frames Statistics "
7560
"VSAN Traffic (Total Frames)\"></TH></TR>") < 0)
7565
/* ******************************************* */