~ubuntu-branches/ubuntu/natty/ntop/natty

« back to all changes in this revision

Viewing changes to report.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2005-01-30 21:59:13 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050130215913-xc3ke963bw49b3k4
Tags: 2:3.0-5
* Updated README.Debian file so users will understand what to do at
  install, closes: #291794, #287802.
* Updated ntop init script to give better output.
* Also changed log directory from /var/lib/ntop to /var/log/ntop,
  closes: #252352.
* Quoted the interface list to allow whitespace, closes: #267248.
* Added a couple of logcheck ignores, closes: #269321, #269319.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 1998-2004 Luca Deri <deri@ntop.org>
 
3
 *
 
4
 *                          http://www.ntop.org/
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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.
 
19
 */
 
20
 
 
21
#include "ntop.h"
 
22
#include "globals-report.h"
 
23
 
 
24
/* *************************** */
 
25
 
 
26
#ifndef WIN32
 
27
static void ignoreSignal(int signalId) {
 
28
  closeNwSocket(&myGlobals.newSock);
 
29
  (void)signal(signalId, ignoreSignal);
 
30
}
 
31
#endif
 
32
 
 
33
/* ******************************* */
 
34
 
 
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"
 
48
               "</ul></p>");
 
49
}
 
50
 
 
51
/* ******************************* */
 
52
 
 
53
void initReports(void) {
 
54
  int i;
 
55
  char value[LEN_SMALL_WORK_BUFFER];
 
56
 
 
57
  myGlobals.columnSort = 0;
 
58
  addDefaultAdminUser();
 
59
 
 
60
  /* Show device table */
 
61
  for(i=0; i<myGlobals.numDevices; i++) {
 
62
    traceEvent(CONST_TRACE_NOISY, "Device %2d. %-30s%s%s%s",
 
63
                 i,
 
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)" : "");
 
70
  }
 
71
 
 
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");
 
85
  }
 
86
  
 
87
  /* Retrieve it */  
 
88
  if(fetchPrefsValue("actualReportDeviceId", value, sizeof(value)) == -1) {
 
89
    myGlobals.actualReportDeviceId = 0;
 
90
  } else {
 
91
    myGlobals.actualReportDeviceId = atoi(value);
 
92
  }
 
93
 
 
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)
 
102
          BufferTooShort();
 
103
        storePrefsValue("actualReportDeviceId", value);
 
104
        break;
 
105
      }
 
106
    }
 
107
  }
 
108
 
 
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)" : "");
 
116
 
 
117
}
 
118
 
 
119
/* **************************************** */
 
120
 
 
121
int reportValues(time_t *lastTime) {
 
122
  if(myGlobals.maxNumLines <= 0)
 
123
    myGlobals.maxNumLines = CONST_NUM_TABLE_ROWS_PER_PAGE;
 
124
 
 
125
  *lastTime = time(NULL) + myGlobals.refreshRate;
 
126
 
 
127
  /*
 
128
    Make sure that the other flags are't set. They have
 
129
    no effect in web mode
 
130
  */
 
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;
 
135
 
 
136
  return(0);
 
137
}
 
138
 
 
139
/* ******************************* */
 
140
 
 
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;
 
147
 
 
148
  if(numPages <= 1) return;
 
149
 
 
150
  if(strchr(url, '?') != NULL)
 
151
    separator = '&';
 
152
  else
 
153
    separator = '?';
 
154
 
 
155
  if(revertOrder == -1)
 
156
    shortBuf[0] = '\0';
 
157
  else {
 
158
    if(snprintf(shortBuf, sizeof(shortBuf),
 
159
                "%s%d", revertOrder == 1 ? "-" : "", numCol) < 0)
 
160
      BufferTooShort();
 
161
  }
 
162
 
 
163
  if(pageNum >= 1) {
 
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)
 
168
      BufferTooShort();
 
169
  } else
 
170
    prevBuf[0] = '\0';
 
171
 
 
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)
 
177
      BufferTooShort();
 
178
  }  else
 
179
    nextBuf[0] = '\0';
 
180
 
 
181
  sendString("<P><FONT FACE=Helvetica><B>");
 
182
  sendString(prevBuf);
 
183
 
 
184
  if(snprintf(buf, sizeof(buf), " [ %d / %d ] ", actPage, numPages) < 0)
 
185
    BufferTooShort();
 
186
  sendString(buf);
 
187
 
 
188
  sendString(nextBuf);
 
189
  sendString("</B></FONT>\n");
 
190
}
 
191
 
 
192
/* ******************************* */
 
193
 
 
194
void printTrafficStatistics(int revertOrder) {
 
195
  Counter unicastPkts, avgPktLen;
 
196
  int i;
 
197
  char buf[LEN_GENERAL_WORK_BUFFER], formatBuf[32], formatBuf1[32];
 
198
  struct stat statbuf;
 
199
  struct pcap_stat pcapStat;
 
200
 
 
201
  unicastPkts = 0;
 
202
  printHTMLheader("Global Traffic Statistics", NULL, 0);
 
203
 
 
204
  sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n");
 
205
 
 
206
  sendString("<TR "TR_ON"><TH "TH_BG" ALIGN=LEFT "DARK_BG">Network Interface(s)</TH>"
 
207
             "<TD "TD_BG" ALIGN=RIGHT>");
 
208
 
 
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>");
 
213
 
 
214
#ifdef INET6
 
215
  sendString("<TH "TH_BG" "DARK_BG">IPv6 Addresses</TH></TR>\n");
 
216
#endif
 
217
 
 
218
  if(myGlobals.rFileName == NULL) {
 
219
    for(i=0; i<myGlobals.numDevices; i++) {
 
220
      if(myGlobals.device[i].activeDevice) {
 
221
        char buf1[128];
 
222
        NtopIfaceAddr *ifaddr;
 
223
        
 
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 : "&nbsp;") < 0)
 
227
          BufferTooShort();
 
228
        sendString(buf);
 
229
 
 
230
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%s</TD>", 
 
231
                    myGlobals.device[i].name) < 0)
 
232
          BufferTooShort();
 
233
        sendString(buf);
 
234
 
 
235
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%s%s</TD>",
 
236
                    getNwInterfaceType(i), myGlobals.device[i].virtualDevice ? " virtual" : "") < 0)
 
237
          BufferTooShort();
 
238
        sendString(buf);
 
239
 
 
240
        sendString("<TD "TD_BG" ALIGN=RIGHT nowrap>&nbsp;");
 
241
        if(myGlobals.device[i].deviceSpeed > 0) {
 
242
          /* The speed is known */
 
243
          sendString(formatAdapterSpeed(myGlobals.device[i].deviceSpeed, formatBuf, sizeof(formatBuf)));
 
244
        } else
 
245
          sendString("&nbsp;");
 
246
        sendString("</TD>");
 
247
 
 
248
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%d</TD>", 
 
249
                    myGlobals.mtuSize[myGlobals.device[i].datalink]) < 0)
 
250
          BufferTooShort();
 
251
        sendString(buf);
 
252
 
 
253
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%d</TD>", 
 
254
                    myGlobals.headerSize[myGlobals.device[i].datalink]) < 0)
 
255
          BufferTooShort();
 
256
        sendString(buf);
 
257
 
 
258
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=CENTER>%s</TD>",
 
259
                    _intoa(myGlobals.device[i].ifAddr, buf1, sizeof(buf1))) < 0)
 
260
          BufferTooShort();
 
261
        sendString(buf);
 
262
 
 
263
#ifdef INET6
 
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)
 
271
              BufferTooShort();
 
272
            sendString(buf);
 
273
          }
 
274
        } else
 
275
          sendString("&nbsp;");
 
276
 
 
277
        sendString("</TD>");
 
278
#endif
 
279
        sendString("</TR>\n");
 
280
      }
 
281
    }
 
282
  } else {
 
283
    if(snprintf(buf, sizeof(buf), "<TR "TR_ON"><TD "TD_BG" ALIGN=CENTER>%s</TD><TD "TD_BG">&nbsp;</TD>", 
 
284
                CONST_PCAP_NW_INTERFACE_FILE) < 0)
 
285
      BufferTooShort();
 
286
    sendString(buf);
 
287
 
 
288
    sendString("<TD "TD_BG" ALIGN=CENTER>");
 
289
 
 
290
    if(strlen(myGlobals.rFileName) < 64)
 
291
      sendString(myGlobals.rFileName);
 
292
    else {
 
293
      for(i=strlen(myGlobals.rFileName); i>0; i--)
 
294
        if((myGlobals.rFileName[i] == '/')
 
295
           || (myGlobals.rFileName[i] == '\\'))
 
296
          break;
 
297
 
 
298
      if(snprintf(buf, sizeof(buf), "...%s", &myGlobals.rFileName[i]) < 0)
 
299
        BufferTooShort();
 
300
      sendString(buf);
 
301
    }
 
302
 
 
303
    sendString("</TD>");
 
304
    sendString("<TD "TD_BG">&nbsp;</TD>");
 
305
    sendString("<TD "TD_BG">&nbsp;</TD>");
 
306
    sendString("<TD "TD_BG">&nbsp;</TD>");
 
307
    sendString("<TD "TD_BG">&nbsp;</TD>");
 
308
#ifdef INET6
 
309
    sendString("<TD "TD_BG">&nbsp;</TD>");
 
310
#endif
 
311
    sendString("</TR>\n");
 
312
  }
 
313
 
 
314
  sendString("</TABLE>"TABLE_OFF);
 
315
  sendString("</TD></TR>\n");
 
316
 
 
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&nbsp;</TD></TR>\n",
 
320
                myGlobals.domainName) < 0)
 
321
      BufferTooShort();
 
322
    sendString(buf);
 
323
  }
 
324
 
 
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)
 
330
      BufferTooShort();
 
331
    sendString(buf);
 
332
  }
 
333
  else {
 
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)
 
337
      BufferTooShort();
 
338
    sendString(buf);
 
339
 
 
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)
 
344
      BufferTooShort();
 
345
    sendString(buf);
 
346
  }
 
347
  
 
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)
 
351
      BufferTooShort();
 
352
    sendString(buf);
 
353
  }
 
354
 
 
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)
 
360
      BufferTooShort();
 
361
    sendString(buf);
 
362
  }
 
363
 
 
364
#ifndef EMBEDDED
 
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");
 
369
#endif
 
370
 
 
371
  if(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value > 0) {
 
372
    Counter dummyCounter;
 
373
 
 
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)
 
378
      BufferTooShort();
 
379
    printSectionTitle(buf);
 
380
    sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n");
 
381
 
 
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");
 
384
 
 
385
    unicastPkts = myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value
 
386
      - myGlobals.device[myGlobals.actualReportDeviceId].broadcastPkts.value
 
387
      - myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value;
 
388
 
 
389
    if(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value <= 0)
 
390
      myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value = 1;
 
391
 
 
392
    if(myGlobals.device[myGlobals.actualReportDeviceId].pcapPtr != NULL) {
 
393
      if(pcap_stats(myGlobals.device[myGlobals.actualReportDeviceId].pcapPtr, &pcapStat) >= 0) {
 
394
        /* 
 
395
           Recent libpcap versions do not report total/cumulative values
 
396
           but their value is reset everytime is read
 
397
        */
 
398
          
 
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;
 
402
        } else {
 
403
          /* The counter is NOT reset at each run */
 
404
          myGlobals.device[myGlobals.actualReportDeviceId].pcapDroppedPkts.value = pcapStat.ps_drop;
 
405
        }
 
406
          
 
407
        if(snprintf(buf, sizeof(buf),
 
408
                    "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Dropped&nbsp;(libpcap)</th>"
 
409
                    "<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",                
 
410
                    getRowColor(),
 
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)
 
415
          BufferTooShort();
 
416
        sendString(buf);
 
417
      }
 
418
    }
 
419
        
 
420
    if(snprintf(buf, sizeof(buf),
 
421
                "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Dropped&nbsp;(ntop)</th>"
 
422
                "<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",            
 
423
                getRowColor(),
 
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)
 
428
      BufferTooShort();
 
429
    sendString(buf);
 
430
 
 
431
    if(snprintf(buf, sizeof(buf),
 
432
                "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Total&nbsp;Received&nbsp;(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)
 
436
      BufferTooShort();
 
437
    sendString(buf);
 
438
 
 
439
 
 
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)
 
445
      BufferTooShort();
 
446
    sendString(buf);
 
447
 
 
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].
 
451
                ethernetPkts.value,
 
452
                formatPkts(unicastPkts, formatBuf, sizeof(formatBuf))) < 0) BufferTooShort();
 
453
    sendString(buf);
 
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)
 
459
      BufferTooShort();
 
460
    sendString(buf);
 
461
 
 
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)
 
467
      BufferTooShort();
 
468
    sendString(buf);
 
469
 
 
470
#ifndef EMBEDDED
 
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");
 
475
#endif
 
476
 
 
477
    if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
 
478
      /*
 
479
        Very rudimental formula. Note that as specified in RMON, packets smaller
 
480
        than 64 or larger than 1518 octets are not counted.
 
481
      */
 
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",
 
484
                  getRowColor(),
 
485
                  formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdPktStats.shortest.value, formatBuf, sizeof(formatBuf))) < 0)
 
486
        BufferTooShort();
 
487
      sendString(buf);
 
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&nbsp;Size</th>"
 
495
                  "<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
 
496
                  getRowColor(), formatPkts(avgPktLen, formatBuf, sizeof(formatBuf))) < 0)
 
497
        BufferTooShort();
 
498
      sendString(buf);
 
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)
 
503
        BufferTooShort();
 
504
      sendString(buf);
 
505
 
 
506
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&lt;&nbsp;64&nbsp;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)
 
512
        BufferTooShort();
 
513
      sendString(buf);
 
514
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&lt;&nbsp;128&nbsp;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)
 
520
        BufferTooShort();
 
521
      sendString(buf);
 
522
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&lt;&nbsp;256&nbsp;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)
 
528
        BufferTooShort();
 
529
      sendString(buf);
 
530
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&lt;&nbsp;512&nbsp;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)
 
536
        BufferTooShort();
 
537
      sendString(buf);
 
538
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&lt;&nbsp;1024&nbsp;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)
 
544
        BufferTooShort();
 
545
      sendString(buf);
 
546
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&lt;&nbsp;1518&nbsp;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)
 
552
        BufferTooShort();
 
553
      sendString(buf);
 
554
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&gt;&nbsp;1518&nbsp;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)
 
560
        BufferTooShort();
 
561
      sendString(buf);
 
562
 
 
563
#ifndef EMBEDDED
 
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");
 
568
#endif
 
569
 
 
570
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Packets&nbsp;too&nbsp;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)
 
576
        BufferTooShort();
 
577
      sendString(buf);
 
578
 
 
579
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Bad&nbsp;Packets&nbsp;(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)
 
585
        BufferTooShort();
 
586
      sendString(buf);
 
587
    }
 
588
 
 
589
    /* ****************** */
 
590
 
 
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%\">");
 
594
        
 
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",
 
598
                    getRowColor(),
 
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)
 
603
          BufferTooShort();
 
604
        sendString(buf);
 
605
#ifdef NOT_YET        
 
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&nbsp;by&nbsp;the&nbsp;kernel</th>"
 
609
                      "<TD "TD_BG" COLSPAN=2 align=right>%s [%.2f %%]</td></TR>\n",
 
610
                      getRowColor(),
 
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)
 
615
            BufferTooShort();
 
616
          sendString(buf);
 
617
        }
 
618
#endif
 
619
      }
 
620
        
 
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].
 
624
                  fcPkts.value,
 
625
                  formatPkts(unicastPkts, formatBuf, sizeof (formatBuf))) < 0) BufferTooShort();
 
626
      sendString(buf);
 
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)
 
633
        BufferTooShort();
 
634
      sendString(buf);
 
635
      
 
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",
 
638
                  getRowColor(),
 
639
                  formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].rcvdFcPktStats.shortest.value,
 
640
                             formatBuf, sizeof (formatBuf))) < 0)
 
641
        BufferTooShort();
 
642
      sendString(buf);
 
643
      
 
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&nbsp;Size</th>"
 
647
                  "<TD "TD_BG" align=right colspan=2>%s bytes</td></TR>\n",
 
648
                  getRowColor(), formatPkts(avgPktLen, formatBuf, sizeof (formatBuf))) < 0)
 
649
        BufferTooShort();
 
650
      sendString(buf);
 
651
      
 
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)
 
657
        BufferTooShort();
 
658
      sendString(buf);
 
659
      
 
660
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">&le&nbsp;36&nbsp;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)
 
667
        BufferTooShort();
 
668
      sendString(buf);
 
669
      
 
670
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&le;&nbsp;48&nbsp;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)
 
677
        BufferTooShort();
 
678
      sendString(buf);
 
679
      
 
680
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&le;&nbsp;52&nbsp;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)
 
687
        BufferTooShort();
 
688
      sendString(buf);
 
689
      
 
690
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&le;&nbsp;68&nbsp;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)
 
697
        BufferTooShort();
 
698
      sendString(buf);
 
699
      
 
700
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&le;&nbsp;104&nbsp;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)
 
707
        BufferTooShort();
 
708
      sendString(buf);
 
709
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&le;&nbsp;548&nbsp;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)
 
716
        BufferTooShort();
 
717
      sendString(buf);
 
718
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&le;&nbsp;1060&nbsp;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)
 
725
        BufferTooShort();
 
726
      sendString(buf);
 
727
      
 
728
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&le;&nbsp;2136&nbsp;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)
 
735
        BufferTooShort();
 
736
      sendString(buf);
 
737
      
 
738
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>&gt;&nbsp;2136&nbsp;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)
 
745
        BufferTooShort();
 
746
      sendString(buf);
 
747
      
 
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");
 
750
      
 
751
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>Packets&nbsp;too&nbsp;long [> %d]</th>"
 
752
                  "<TD "TD_BG" align=right>%.1f%%</td><TD "TD_BG" align=right>%s</td></TR>\n",
 
753
                  getRowColor(), 2136,
 
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)
 
758
        BufferTooShort();
 
759
      sendString(buf);
 
760
      
 
761
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" "DARK_BG" align=left>Bad&nbsp;EOF&nbsp;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)
 
768
        BufferTooShort();
 
769
      sendString(buf);
 
770
          
 
771
    }
 
772
    /* ****************** */
 
773
 
 
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",
 
777
                getRowColor(),
 
778
                formatBytes(myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value, 1, formatBuf, sizeof(formatBuf)),
 
779
                formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value, formatBuf, sizeof(formatBuf))) < 0)
 
780
      BufferTooShort();
 
781
    sendString(buf);
 
782
 
 
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)
 
787
      BufferTooShort();
 
788
    sendString(buf);
 
789
 
 
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",
 
793
                  getRowColor(),
 
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)
 
797
        BufferTooShort();
 
798
      sendString(buf);
 
799
    }
 
800
 
 
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;
 
806
    else
 
807
      dummyCounter = 0;
 
808
 
 
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)
 
812
      BufferTooShort();
 
813
    sendString(buf);
 
814
 
 
815
#ifndef EMBEDDED
 
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");
 
819
#endif
 
820
 
 
821
    /* ********************* */
 
822
 
 
823
    if(myGlobals.device[myGlobals.actualReportDeviceId].ipPkts.value > 0) {
 
824
      int avgPktTTL;
 
825
 
 
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);
 
835
 
 
836
      if(avgPktTTL > 0) {
 
837
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">Average&nbsp;TTL</th>"
 
838
                    "<TD "TD_BG" align=right COLSPAN=2>%d</td></TR>\n",
 
839
                    getRowColor(), avgPktTTL) < 0)
 
840
          BufferTooShort();
 
841
        sendString(buf);
 
842
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">TTL &lt; 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)
 
849
          BufferTooShort();
 
850
        sendString(buf);
 
851
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">32 &lt; TTL &lt; 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)
 
858
          BufferTooShort();
 
859
        sendString(buf);
 
860
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">64 &lt; TTL &lt; 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)
 
867
          BufferTooShort();
 
868
        sendString(buf);
 
869
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">96 &lt; TTL &lt; 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)
 
876
          BufferTooShort();
 
877
        sendString(buf);
 
878
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">128 &lt; TTL &lt; 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)
 
885
          BufferTooShort();
 
886
        sendString(buf);
 
887
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">160 &lt; TTL &lt; 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)
 
894
          BufferTooShort();
 
895
        sendString(buf);
 
896
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">192 &lt; TTL &lt; 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)
 
903
          BufferTooShort();
 
904
        sendString(buf);
 
905
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" align=left "DARK_BG">224 &lt; TTL &lt; 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)
 
912
          BufferTooShort();
 
913
        sendString(buf);
 
914
 
 
915
#ifndef EMBEDDED
 
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");
 
919
#endif
 
920
      }
 
921
    }
 
922
 
 
923
    sendString("</TABLE>"TABLE_OFF"</TR>");
 
924
    /* ************************ */
 
925
 
 
926
#ifndef EMBEDDED
 
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");
 
932
#endif
 
933
 
 
934
    if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
 
935
      updateThpt(0);
 
936
 
 
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&nbsp;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)
 
943
        BufferTooShort();
 
944
      sendString(buf);
 
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&nbsp;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)
 
951
        BufferTooShort();
 
952
      sendString(buf);
 
953
 
 
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&nbsp;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)
 
960
        BufferTooShort();
 
961
      sendString(buf);
 
962
 
 
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&nbsp;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)
 
969
        BufferTooShort();
 
970
      sendString(buf);
 
971
 
 
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&nbsp;Pkts/sec</td></TR>\n",
 
975
                  getRowColor(),
 
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)
 
981
        BufferTooShort();
 
982
      sendString(buf);
 
983
 
 
984
      sendString("</TABLE>"TABLE_OFF"</TR>\n");
 
985
    }
 
986
  }
 
987
 
 
988
  /* ********************* */
 
989
 
 
990
#ifndef EMBEDDED
 
991
  /* RRD */
 
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)
 
996
    BufferTooShort();
 
997
  
 
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&amp;key=interfaces/%s&amp;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> ]"
 
1006
                "</TD></TR>\n",
 
1007
                getRowColor(), myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName,
 
1008
                myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName) < 0)
 
1009
      BufferTooShort();
 
1010
    sendString(buf);
 
1011
  }
 
1012
#endif
 
1013
  /* ********************* */
 
1014
 
 
1015
  sendString("</TABLE></CENTER>\n");
 
1016
 
 
1017
  if (!myGlobals.printFcOnly) {
 
1018
    printProtoTraffic();
 
1019
    sendString("<p>\n");
 
1020
    printIpProtocolDistribution(FLAG_HOSTLINK_HTML_FORMAT, revertOrder);
 
1021
  }
 
1022
  if (!myGlobals.noFc) {
 
1023
    sendString("<p>\n");
 
1024
    printFcProtocolDistribution(FLAG_HOSTLINK_HTML_FORMAT, revertOrder);
 
1025
  }
 
1026
}
 
1027
 
 
1028
/* ******************************* */
 
1029
 
 
1030
int combineReportTypeLocality(int reportTypeReq, LocalityDisplayPolicy showLocalityMode) {
 
1031
  int rc;
 
1032
 
 
1033
  rc=reportTypeReq;
 
1034
 
 
1035
  switch(reportTypeReq) {
 
1036
    case SORT_DATA_HOST_TRAFFIC:
 
1037
      switch(showLocalityMode) {
 
1038
        case showOnlySent:
 
1039
          rc = SORT_DATA_SENT_HOST_TRAFFIC;
 
1040
          break;
 
1041
        case showOnlyReceived:
 
1042
          rc = SORT_DATA_RCVD_HOST_TRAFFIC;
 
1043
      }
 
1044
      break;
 
1045
    case SORT_DATA_PROTOS:
 
1046
      switch(showLocalityMode) {
 
1047
        case showOnlySent:
 
1048
          rc = SORT_DATA_SENT_PROTOS;
 
1049
          break;
 
1050
        case showOnlyReceived:
 
1051
          rc = SORT_DATA_RECEIVED_PROTOS;
 
1052
      }
 
1053
      break;
 
1054
    case SORT_DATA_IP:
 
1055
      switch(showLocalityMode) {
 
1056
        case showOnlySent:
 
1057
          rc = SORT_DATA_SENT_IP;
 
1058
          break;
 
1059
        case showOnlyReceived:
 
1060
          rc = SORT_DATA_RECEIVED_IP;
 
1061
      }
 
1062
      break;
 
1063
    case SORT_DATA_THPT:
 
1064
      switch(showLocalityMode) {
 
1065
        case showOnlySent:
 
1066
          rc = SORT_DATA_SENT_THPT;
 
1067
          break;
 
1068
        case showOnlyReceived:
 
1069
          rc = SORT_DATA_RECEIVED_THPT;
 
1070
      }
 
1071
      break;
 
1072
  }
 
1073
 
 
1074
  return(rc);
 
1075
 
 
1076
}
 
1077
 
 
1078
/* ******************************* */
 
1079
 
 
1080
void printHostsTraffic(int reportTypeReq,
 
1081
                       int sortedColumn,
 
1082
                       int revertOrder,
 
1083
                       int pageNum,
 
1084
                       char* url,
 
1085
                       HostsDisplayPolicy showHostsMode,
 
1086
                       LocalityDisplayPolicy showLocalityMode) {
 
1087
  u_int idx, idx1, numEntries=0;
 
1088
  int printedEntries=0, hourId, maxHosts;
 
1089
  char theDate[8];
 
1090
  struct tm t;
 
1091
  HostTraffic *el;
 
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];
 
1101
  int reportType;
 
1102
 
 
1103
  reportType=combineReportTypeLocality(reportTypeReq, showLocalityMode);
 
1104
 
 
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)
 
1111
      BufferTooShort();
 
1112
    break;
 
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)
 
1117
      BufferTooShort();
 
1118
    break;
 
1119
  case SORT_DATA_RECEIVED_IP:
 
1120
  case SORT_DATA_SENT_IP:
 
1121
  case SORT_DATA_IP:
 
1122
    if(snprintf(buf, sizeof(buf), "Network Traffic [TCP/IP]: ") < 0)
 
1123
      BufferTooShort();
 
1124
    break;
 
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)
 
1129
      BufferTooShort();
 
1130
    break;
 
1131
  default:
 
1132
    if(snprintf(buf, sizeof(buf), "?: ") < 0)
 
1133
      BufferTooShort();
 
1134
    break;
 
1135
  }
 
1136
 
 
1137
  switch(showHostsMode) {
 
1138
    case showAllHosts:
 
1139
      strncat(buf, "All Hosts", (sizeof(buf) - strlen(buf) - 1));
 
1140
      break;
 
1141
    case showOnlyLocalHosts:
 
1142
      strncat(buf, "Local Hosts", (sizeof(buf) - strlen(buf) - 1));
 
1143
      break;
 
1144
    case showOnlyRemoteHosts:
 
1145
      strncat(buf, "Remote Hosts", (sizeof(buf) - strlen(buf) - 1));
 
1146
      break;
 
1147
  }
 
1148
 
 
1149
  switch(showLocalityMode) {
 
1150
    case showSentReceived:
 
1151
      strncat(buf, " - Data Sent+Received", (sizeof(buf) - strlen(buf) - 1));
 
1152
      break;
 
1153
    case showOnlySent:
 
1154
      strncat(buf, " - Data Sent", (sizeof(buf) - strlen(buf) - 1));
 
1155
      break;
 
1156
    case showOnlyReceived:
 
1157
      strncat(buf, " - Data Received", (sizeof(buf) - strlen(buf) - 1));
 
1158
      break;
 
1159
  }
 
1160
 
 
1161
  printHTMLheader(buf, NULL, 0);
 
1162
  printHeader(reportTypeReq, revertOrder, abs(sortedColumn), showHostsMode, showLocalityMode);
 
1163
 
 
1164
  strftime(theDate, 8, CONST_TOD_HOUR_TIMESPEC, localtime_r(&myGlobals.actTime, &t));
 
1165
  hourId = atoi(theDate);
 
1166
 
 
1167
  maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno;
 
1168
  /* save ths as it can change */
 
1169
 
 
1170
  tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*),
 
1171
                                                        "printHostsTraffic");
 
1172
  if(tmpTable == NULL)
 
1173
      return;
 
1174
 
 
1175
  for(el=getFirstHost(myGlobals.actualReportDeviceId);
 
1176
      el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
 
1177
    if(!isFcHost (el) && (broadcastHost(el) == 0)) {
 
1178
      u_char addHost;
 
1179
      
 
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')) {
 
1187
          continue;
 
1188
        }
 
1189
 
 
1190
        addHost = 1;
 
1191
 
 
1192
        switch(myGlobals.hostsDisplayPolicy) {
 
1193
        case showOnlyLocalHosts:
 
1194
          if(!subnetPseudoLocalHost(el)) addHost = 0;
 
1195
          break;
 
1196
        case showOnlyRemoteHosts:
 
1197
          if(subnetPseudoLocalHost(el)) addHost = 0;
 
1198
          break;
 
1199
        }
 
1200
 
 
1201
        if(addHost) {
 
1202
          tmpTable[numEntries++] = el;  
 
1203
          if(numEntries >= maxHosts)
 
1204
            break;
 
1205
        }
 
1206
      }
 
1207
    }
 
1208
  } /* for */
 
1209
 
 
1210
  if(numEntries > 0) {
 
1211
    /*
 
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
 
1215
    */
 
1216
 
 
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 */
 
1221
    else
 
1222
      myGlobals.columnSort = sortedColumn;
 
1223
 
 
1224
#ifdef DEBUG
 
1225
    traceEvent(CONST_TRACE_INFO, ">reportType=%d/sortedColumn=%d/myGlobals.columnSort=%d<",
 
1226
               reportType, sortedColumn, myGlobals.columnSort);
 
1227
#endif
 
1228
 
 
1229
    myGlobals.reportKind = reportType;
 
1230
    /* if(myGlobals.columnSort == 0) myGlobals.reportKind = 0;*/
 
1231
 
 
1232
    qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpFctn);
 
1233
 
 
1234
    switch(reportType) {
 
1235
    case SORT_DATA_RECEIVED_PROTOS:
 
1236
    case SORT_DATA_SENT_PROTOS:
 
1237
      totEthBytesSent = totEthBytesRcvd = 0;
 
1238
 
 
1239
      for(idx=0; idx<numEntries; idx++) {
 
1240
        if(tmpTable[idx] != NULL) {
 
1241
          totEthBytesSent += tmpTable[idx]->bytesSent.value;
 
1242
          totEthBytesRcvd += tmpTable[idx]->bytesRcvd.value;
 
1243
        }
 
1244
      }
 
1245
 
 
1246
      /* Avoid core dumps */
 
1247
      if(totEthBytesSent == 0) totEthBytesSent = 1;
 
1248
      if(totEthBytesRcvd == 0) totEthBytesRcvd = 1;
 
1249
      break;
 
1250
    case SORT_DATA_PROTOS:
 
1251
      totEthBytes = 0;
 
1252
 
 
1253
      for(idx=0; idx<numEntries; idx++) {
 
1254
        if(tmpTable[idx] != NULL) {
 
1255
          totEthBytes += tmpTable[idx]->bytesSent.value +
 
1256
            tmpTable[idx]->bytesRcvd.value;
 
1257
        }
 
1258
      }
 
1259
 
 
1260
      /* Avoid core dumps */
 
1261
      if(totEthBytes == 0) totEthBytes = 1;
 
1262
      break;
 
1263
    case SORT_DATA_RECEIVED_IP:
 
1264
    case SORT_DATA_SENT_IP:
 
1265
      totIpBytesSent = totIpBytesRcvd = 0;
 
1266
 
 
1267
      for(idx=0; idx<numEntries; idx++) {
 
1268
        if(tmpTable[idx] != NULL) {
 
1269
          totIpBytesSent += tmpTable[idx]->ipBytesSent.value;
 
1270
          totIpBytesRcvd += tmpTable[idx]->ipBytesRcvd.value;
 
1271
        }
 
1272
      }
 
1273
 
 
1274
      /* Avoid core dumps */
 
1275
      if(totIpBytesSent == 0) totIpBytesSent = 1;
 
1276
      if(totIpBytesRcvd == 0) totIpBytesRcvd = 1;
 
1277
      break;
 
1278
    case SORT_DATA_IP:
 
1279
      totIpBytes = 0;
 
1280
 
 
1281
      for(idx=0; idx<numEntries; idx++) {
 
1282
        if(tmpTable[idx] != NULL) {
 
1283
          totIpBytes += tmpTable[idx]->ipBytesSent.value +
 
1284
            tmpTable[idx]->ipBytesRcvd.value;
 
1285
        }
 
1286
      }
 
1287
 
 
1288
      /* Avoid core dumps */
 
1289
      if(totIpBytes == 0) totIpBytes = 1;
 
1290
      break;
 
1291
    }
 
1292
 
 
1293
#ifdef DEBUG
 
1294
    traceEvent(CONST_TRACE_INFO, "totIpBytesSent=%u, totIpBytesRcvd=%u totIpBytes=%u",
 
1295
               totIpBytesSent, totIpBytesRcvd, totIpBytes);
 
1296
#endif
 
1297
 
 
1298
    for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
1299
      int i;
 
1300
      char webHostName[LEN_GENERAL_WORK_BUFFER];
 
1301
 
 
1302
      if(revertOrder)
 
1303
        el = tmpTable[numEntries-idx-1];
 
1304
      else
 
1305
        el = tmpTable[idx];
 
1306
 
 
1307
      if(el != NULL) {
 
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;
 
1313
          break;
 
1314
        case SORT_DATA_PROTOS:
 
1315
          totPercent = (100*(float) (el->bytesSent.value + el->bytesRcvd.value) )/totEthBytes;
 
1316
          break;
 
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;
 
1321
          break;
 
1322
        case SORT_DATA_IP:
 
1323
          totPercent = (100*(float) (el->ipBytesSent.value + el->ipBytesRcvd.value) )/totIpBytes;
 
1324
          break;
 
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:
 
1329
        case TRAFFIC_STATS:
 
1330
        case SORT_DATA_HOST_TRAFFIC:
 
1331
        case SORT_DATA_THPT:
 
1332
          sentPercent = rcvdPercent = 0;
 
1333
          break;
 
1334
        }
 
1335
 
 
1336
        /* Fixed buffer overflow.
 
1337
           Courtesy of Rainer Tammer <rainer.tammer@spg.schulergroup.com>
 
1338
        */
 
1339
 
 
1340
        strncpy(webHostName, makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 1, 
 
1341
                                          hostLinkBuf, sizeof(hostLinkBuf)),
 
1342
                sizeof(webHostName));
 
1343
 
 
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();
 
1366
          sendString(buf);
 
1367
 
 
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();
 
1377
          sendString(buf);
 
1378
 
 
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();
 
1384
            sendString(buf);
 
1385
 
 
1386
            idx1++, protoList = protoList->next;
 
1387
          }
 
1388
 
 
1389
          if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
 
1390
                      formatBytes(el->otherRcvd.value, 1, formatBuf, sizeof(formatBuf))) < 0) BufferTooShort();
 
1391
          sendString(buf);
 
1392
          break;
 
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();
 
1413
 
 
1414
          sendString(buf);
 
1415
 
 
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();
 
1425
          sendString(buf);
 
1426
 
 
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();
 
1432
            sendString(buf);
 
1433
 
 
1434
            idx1++, protoList = protoList->next;
 
1435
          }
 
1436
 
 
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();
 
1441
          sendString(buf);
 
1442
          break;
 
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();
 
1466
 
 
1467
          sendString(buf);
 
1468
 
 
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();
 
1478
          sendString(buf);
 
1479
 
 
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();
 
1485
            sendString(buf);
 
1486
 
 
1487
            idx1++, protoList = protoList->next;
 
1488
          }
 
1489
 
 
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();
 
1494
          sendString(buf);
 
1495
 
 
1496
          break;
 
1497
        case SORT_DATA_RECEIVED_IP:
 
1498
          {
 
1499
            Counter totalIPTraffic=0;
 
1500
 
 
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)
 
1506
              BufferTooShort();
 
1507
            sendString(buf);
 
1508
 
 
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)
 
1516
                BufferTooShort();
 
1517
              sendString(buf);
 
1518
            }
 
1519
 
 
1520
            /* Rounding may cause troubles */
 
1521
            if(el->ipBytesRcvd.value > totalIPTraffic)
 
1522
              totalIPTraffic = el->ipBytesRcvd.value - totalIPTraffic;
 
1523
            else
 
1524
              totalIPTraffic = 0;
 
1525
            if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
 
1526
                        formatBytes(totalIPTraffic, 1, formatBuf, sizeof(formatBuf))) < 0)
 
1527
              BufferTooShort();
 
1528
            sendString(buf);
 
1529
          }
 
1530
          break;
 
1531
        case SORT_DATA_SENT_IP:
 
1532
          {
 
1533
            Counter totalIPTraffic=0;
 
1534
 
 
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)
 
1540
              BufferTooShort();
 
1541
            sendString(buf);
 
1542
 
 
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)
 
1550
                BufferTooShort();
 
1551
              sendString(buf);
 
1552
            }
 
1553
 
 
1554
            /* Rounding may cause troubles */
 
1555
            if(el->ipBytesSent.value > totalIPTraffic)
 
1556
              totalIPTraffic = el->ipBytesSent.value - totalIPTraffic;
 
1557
            else
 
1558
              totalIPTraffic = 0;
 
1559
            if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
 
1560
                        formatBytes(totalIPTraffic, 1, formatBuf, sizeof(formatBuf))) < 0)
 
1561
              BufferTooShort();
 
1562
            sendString(buf);
 
1563
          }
 
1564
          break;
 
1565
        case SORT_DATA_IP:
 
1566
          {
 
1567
            Counter totalIPTraffic=0;
 
1568
 
 
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)
 
1574
              BufferTooShort();
 
1575
            sendString(buf);
 
1576
 
 
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)
 
1588
                BufferTooShort();
 
1589
              sendString(buf);
 
1590
            }
 
1591
 
 
1592
            /* Rounding may cause troubles */
 
1593
            if(el->ipBytesSent.value+el->ipBytesRcvd.value > totalIPTraffic)
 
1594
              totalIPTraffic = el->ipBytesSent.value + el->ipBytesRcvd.value - totalIPTraffic;
 
1595
            else
 
1596
              totalIPTraffic = 0;
 
1597
            if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
 
1598
                        formatBytes(totalIPTraffic, 1, formatBuf, sizeof(formatBuf))) < 0)
 
1599
              BufferTooShort();
 
1600
            sendString(buf);
 
1601
          }
 
1602
          break;
 
1603
        case SORT_DATA_RECEIVED_THPT:
 
1604
          {
 
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&nbsp;Pkts/sec</TD>"
 
1610
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>"
 
1611
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;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)
 
1619
              BufferTooShort();
 
1620
            sendString(buf);
 
1621
          }
 
1622
          break;
 
1623
        case SORT_DATA_SENT_THPT:
 
1624
          {
 
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&nbsp;Pkts/sec</TD>"
 
1630
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>"
 
1631
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;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)
 
1639
              BufferTooShort();
 
1640
            sendString(buf);
 
1641
          }
 
1642
          break;
 
1643
        case SORT_DATA_THPT:
 
1644
          {
 
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&nbsp;Pkts/sec</TD>"
 
1650
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>"
 
1651
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;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)),
 
1656
                        el->actualTPktThpt,
 
1657
                        el->averageTPktThpt,
 
1658
                        el->peakTPktThpt) < 0)
 
1659
              BufferTooShort();
 
1660
            sendString(buf);
 
1661
          }
 
1662
          break;
 
1663
        case SORT_DATA_RCVD_HOST_TRAFFIC:
 
1664
        case SORT_DATA_SENT_HOST_TRAFFIC:
 
1665
        case SORT_DATA_HOST_TRAFFIC:
 
1666
        case TRAFFIC_STATS:
 
1667
          {
 
1668
            if(snprintf(buf, sizeof(buf), "<TR %s>%s", getRowColor(), webHostName) < 0)
 
1669
              BufferTooShort();
 
1670
            sendString(buf);
 
1671
            printHostThtpShort(el, reportType, hourId);
 
1672
          }
 
1673
          break;
 
1674
        }
 
1675
 
 
1676
        sendString("</TR>\n");
 
1677
 
 
1678
        /* Avoid huge tables */
 
1679
        if(printedEntries++ > myGlobals.maxNumLines)
 
1680
          break;
 
1681
      }
 
1682
    }
 
1683
  } else
 
1684
    idx = 0;
 
1685
 
 
1686
  sendString("\n</TABLE>"TABLE_OFF"\n");
 
1687
 
 
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:
 
1695
    break;
 
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:
 
1701
  case SORT_DATA_IP:
 
1702
    sendString("<P><I>Note: These counters do not include broadcasts and will not equal the 'Global Protocol Distribution'</I></P>\n");
 
1703
    break;
 
1704
  }
 
1705
 
 
1706
  sendString("</CENTER>\n");
 
1707
 
 
1708
  printFooter(reportType);
 
1709
 
 
1710
  addPageIndicator(url, pageNum, numEntries, myGlobals.maxNumLines,
 
1711
                   revertOrder, abs(sortedColumn));
 
1712
 
 
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"
 
1716
             "</ul><p>\n");
 
1717
  
 
1718
  myGlobals.lastRefreshTime = myGlobals.actTime;
 
1719
  free(tmpTable);
 
1720
}
 
1721
 
 
1722
/* ******************************* */
 
1723
 
 
1724
void printMulticastStats(int sortedColumn /* ignored so far */,
 
1725
                         int revertOrder,
 
1726
                         int pageNum) {
 
1727
  u_int idx, numEntries=0, maxHosts;
 
1728
  int printedEntries=0, i;
 
1729
  HostTraffic *el;
 
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];
 
1734
 
 
1735
  printHTMLheader("Multicast Statistics", NULL, 0);
 
1736
 
 
1737
  memset(buf, 0, sizeof(buf));
 
1738
  maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
 
1739
 
 
1740
  tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "printMulticastStats");
 
1741
  if(tmpTable == NULL)
 
1742
      return;
 
1743
 
 
1744
  /* All the ALT tags courtesy of "Burton M. Strauss III" <BStrauss3@attbi.com> */
 
1745
  if(revertOrder) {
 
1746
    sign = "";
 
1747
    arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
1748
  } else {
 
1749
    sign = "-";
 
1750
    arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
1751
  }
 
1752
 
 
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;
 
1758
 
 
1759
    if(numEntries >= maxHosts)
 
1760
      break;
 
1761
  }
 
1762
 
 
1763
  if(numEntries > 0) {
 
1764
    myGlobals.columnSort = sortedColumn; /* Host name */
 
1765
 
 
1766
    if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", CONST_MULTICAST_STATS_HTML, sign) < 0)
 
1767
      BufferTooShort();
 
1768
    if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", CONST_MULTICAST_STATS_HTML) < 0)
 
1769
      BufferTooShort();
 
1770
 
 
1771
    for(i=0; i<=5; i++)
 
1772
      if(abs(myGlobals.columnSort) == i)
 
1773
        arrow[i] = arrowGif, theAnchor[i] = htmlAnchor;
 
1774
      else
 
1775
        arrow[i] = "", theAnchor[i] = htmlAnchor1;
 
1776
    
 
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>"
 
1784
                "</TR>\n",
 
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();
 
1792
    sendString(buf);
 
1793
 
 
1794
    qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpMulticastFctn);
 
1795
 
 
1796
    for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
1797
      if(revertOrder)
 
1798
        el = tmpTable[numEntries-idx-1];
 
1799
      else
 
1800
        el = tmpTable[idx];
 
1801
 
 
1802
      if(el != NULL) {
 
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>"
 
1806
                    "</TR>\n",
 
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();
 
1812
 
 
1813
        sendString(buf);
 
1814
 
 
1815
        /* Avoid huge tables */
 
1816
        if(printedEntries++ > myGlobals.maxNumLines)
 
1817
          break;
 
1818
      }
 
1819
    }
 
1820
 
 
1821
    sendString("</TABLE>"TABLE_OFF"\n");
 
1822
    sendString("</CENTER>\n");
 
1823
 
 
1824
    addPageIndicator(CONST_MULTICAST_STATS_HTML, pageNum, numEntries, myGlobals.maxNumLines,
 
1825
                     revertOrder, abs(sortedColumn));
 
1826
 
 
1827
    printFooterHostLink();
 
1828
 
 
1829
  } else
 
1830
    printNoDataYet();
 
1831
 
 
1832
  free(tmpTable);
 
1833
}
 
1834
 
 
1835
/* ******************************* */
 
1836
 
 
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 */;
 
1841
  HostTraffic *el;
 
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];
 
1846
 
 
1847
  printHTMLheader("Host Information", NULL, 0);
 
1848
  
 
1849
  memset(buf, 0, sizeof(buf));
 
1850
  maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
 
1851
 
 
1852
  tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "printHostsInfo");
 
1853
  if(tmpTable == NULL)
 
1854
      return;
 
1855
 
 
1856
  if(revertOrder) {
 
1857
    sign = "";
 
1858
    arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
1859
  } else {
 
1860
    sign = "-";
 
1861
    arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
1862
  }
 
1863
 
 
1864
  myGlobals.columnSort = sortedColumn;
 
1865
 
 
1866
  for(el=getFirstHost(myGlobals.actualReportDeviceId);
 
1867
      el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
 
1868
    unsigned short actUsage, actUsageS, actUsageR;
 
1869
 
 
1870
    if(isFcHost (el) || broadcastHost(el)) continue;
 
1871
 
 
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));
 
1878
 
 
1879
    el->actBandwidthUsage = actUsage;
 
1880
    if(el->actBandwidthUsage > maxBandwidthUsage)
 
1881
      maxBandwidthUsage = actUsage;
 
1882
    el->actBandwidthUsageS = actUsageS;
 
1883
    el->actBandwidthUsageR = actUsageR;
 
1884
 
 
1885
    tmpTable[numEntries++] = el;
 
1886
    getHostAS(el);
 
1887
 
 
1888
    if(numEntries >= maxHosts)
 
1889
      break;
 
1890
  }
 
1891
 
 
1892
  if(numEntries > 0) {
 
1893
    int i;
 
1894
 
 
1895
    qsort(tmpTable, numEntries, sizeof(HostTraffic*), sortHostFctn);
 
1896
 
 
1897
    if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=\"/%s?col=%s", CONST_HOSTS_INFO_HTML, sign) < 0)
 
1898
      BufferTooShort();
 
1899
    if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=\"/%s?col=", CONST_HOSTS_INFO_HTML) < 0)
 
1900
      BufferTooShort();
 
1901
 
 
1902
    for(i=1; i<=10; i++) {
 
1903
      if(abs(myGlobals.columnSort) == i) {
 
1904
        arrow[i] = arrowGif;
 
1905
        theAnchor[i] = htmlAnchor;
 
1906
      } else {
 
1907
        arrow[i] = "";
 
1908
        theAnchor[i] = htmlAnchor1;
 
1909
      }
 
1910
    }
 
1911
 
 
1912
    if(abs(myGlobals.columnSort) == FLAG_DOMAIN_DUMMY_IDX) {
 
1913
      arrow[0] = arrowGif;
 
1914
      theAnchor[0] = htmlAnchor;
 
1915
    } else {
 
1916
      arrow[0] = "";
 
1917
      theAnchor[0] = htmlAnchor1;
 
1918
    }
 
1919
 
 
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&nbsp;Address%s</A></TH>\n"
 
1925
                  "<TH "TH_BG">%s3\">MAC&nbsp;Address%s</A></TH>\n"
 
1926
                  "<TH "TH_BG">%s6\">Other&nbsp;Name(s)%s</A></TH>\n"
 
1927
                  "<TH "TH_BG">%s4\">Bandwidth%s</A></TH>\n"
 
1928
                  "<TH "TH_BG">%s5\">Nw&nbsp;Board&nbsp;Vendor%s</A></TH>\n"
 
1929
                  "<TH "TH_BG">%s7\">Hops&nbsp;Distance%s</A></TH>\n"
 
1930
                  "<TH "TH_BG">%s8\">Host&nbsp;Contacts%s</A></TH>\n"
 
1931
                  "<TH "TH_BG">%s9\">Age%s</A></TH>\n"
 
1932
                  "<TH "TH_BG">%s10\">AS%s</A></TH>"
 
1933
                  "</TR>\n",
 
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]
 
1945
                  ) < 0)
 
1946
        BufferTooShort();
 
1947
    } else {
 
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&nbsp;Address%s</A></TH>\n"
 
1952
                  "<TH "TH_BG">%s6\">Other&nbsp;Name(s)%s</A></TH>\n"
 
1953
                  "<TH "TH_BG">%s4\">Bandwidth%s</A></TH>\n"
 
1954
                  "<TH "TH_BG">%s7\">Hops&nbsp;Distance%s</A></TH>\n"
 
1955
                  "<TH "TH_BG">%s8\">Host&nbsp;Contacts%s</A></TH>\n"
 
1956
                  "<TH "TH_BG">%s9\">Age%s</A></TH>\n"
 
1957
                  "<TH "TH_BG">%s10\">AS%s</A></TH>"
 
1958
                  "</TR>\n",
 
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]
 
1968
                  ) < 0)
 
1969
        BufferTooShort();
 
1970
    }
 
1971
    sendString(buf);
 
1972
 
 
1973
    for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
1974
      if(revertOrder)
 
1975
        el = tmpTable[numEntries-idx-1];
 
1976
      else
 
1977
        el = tmpTable[idx];
 
1978
 
 
1979
      if(el != NULL) {
 
1980
        char *tmpName1, *tmpName2, *tmpName3, sniffedName[MAXDNAME];
 
1981
        int displaySniffedName=0;
 
1982
 
 
1983
        tmpName1 = el->hostNumIpAddress;
 
1984
 
 
1985
        if((tmpName1[0] == '\0') || (strcmp(tmpName1, "0.0.0.0") == 0))
 
1986
          tmpName1 = myGlobals.separator;
 
1987
 
 
1988
        if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
 
1989
          tmpName2 = getVendorInfo(el->ethAddress, 1);
 
1990
          if(tmpName2[0] == '\0')
 
1991
            tmpName2 = myGlobals.separator;
 
1992
 
 
1993
          tmpName3 = el->ethAddressString;
 
1994
          if((tmpName3[0] == '\0')
 
1995
             || (strcmp(tmpName3, "00:00:00:00:00:00") == 0))
 
1996
            tmpName3 = myGlobals.separator;
 
1997
        } else {
 
1998
          tmpName2 = myGlobals.separator;
 
1999
          tmpName3 = myGlobals.separator;
 
2000
        }
 
2001
 
 
2002
        if(!addrnull(&el->hostIpAddress)
 
2003
           && (getSniffedDNSName(el->hostNumIpAddress,
 
2004
                                 sniffedName, sizeof(sniffedName)))) {
 
2005
#ifdef DEBUG
 
2006
          traceEvent(CONST_TRACE_INFO, "%s <=> %s [%s/%s]",
 
2007
                     el->hostNumIpAddress, sniffedName,
 
2008
                     el->hostResolvedName, el->hostNumIpAddress);
 
2009
#endif
 
2010
 
 
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';
 
2016
 
 
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);
 
2019
            } else
 
2020
              displaySniffedName=1;
 
2021
          }
 
2022
        }
 
2023
 
 
2024
        if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>", getRowColor()) < 0)
 
2025
          BufferTooShort();
 
2026
        sendString(buf);
 
2027
 
 
2028
        sendString(makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 1, hostLinkBuf, sizeof(hostLinkBuf)));
 
2029
 
 
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)
 
2034
            BufferTooShort();
 
2035
        } else {
 
2036
          if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>\n",
 
2037
                      tmpName1) < 0)
 
2038
            BufferTooShort();
 
2039
        }
 
2040
        sendString(buf);
 
2041
 
 
2042
        sendString("<TD "TD_BG" ALIGN=RIGHT NOWRAP>");
 
2043
 
 
2044
        if(el->nonIPTraffic && displaySniffedName) {
 
2045
          short numAddresses = 0;
 
2046
 
 
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&nbsp;%s@%s&nbsp;[%s]", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
 
2051
                            el->nonIPTraffic->nbAccountName, el->nonIPTraffic->nbHostName,
 
2052
                            el->nonIPTraffic->nbDomainName) < 0)
 
2053
                  BufferTooShort();
 
2054
              } else {
 
2055
                if(snprintf(buf, sizeof(buf), "%s&nbsp;%s@%s", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
 
2056
                            el->nonIPTraffic->nbAccountName, el->nonIPTraffic->nbHostName) < 0)
 
2057
                  BufferTooShort();
 
2058
              }
 
2059
            } else {
 
2060
              if((el->nonIPTraffic->nbDomainName != NULL) && (el->nonIPTraffic->nbDomainName[0] != '0')) {
 
2061
                if(snprintf(buf, sizeof(buf), "%s&nbsp;%s&nbsp;[%s]", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
 
2062
                            el->nonIPTraffic->nbHostName, el->nonIPTraffic->nbDomainName) < 0)
 
2063
                  BufferTooShort();
 
2064
              } else {
 
2065
                if(snprintf(buf, sizeof(buf), "%s&nbsp;%s", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
 
2066
                            el->nonIPTraffic->nbHostName) < 0)
 
2067
                  BufferTooShort();
 
2068
              }
 
2069
            }
 
2070
            sendString(buf);
 
2071
            numAddresses++;
 
2072
          } else if(el->nonIPTraffic->nbHostName) {
 
2073
            if(snprintf(buf, sizeof(buf), "%s&nbsp;%s", getOSFlag(el, "Windows", 0, osBuf, sizeof(osBuf)),
 
2074
                        el->nonIPTraffic->nbHostName) < 0) BufferTooShort();
 
2075
            sendString(buf);
 
2076
            numAddresses++;
 
2077
          }
 
2078
 
 
2079
          if(el->nonIPTraffic->nbDescr) {
 
2080
            if(snprintf(buf, sizeof(buf), ":&nbsp;%s", el->nonIPTraffic->nbDescr) < 0)
 
2081
              BufferTooShort();
 
2082
            sendString(buf);
 
2083
          }
 
2084
 
 
2085
          if (displaySniffedName) {
 
2086
            if(numAddresses > 0) sendString("/");
 
2087
            if(snprintf(buf, sizeof(buf), "%s", sniffedName) < 0)
 
2088
              BufferTooShort();
 
2089
            sendString(buf);
 
2090
            numAddresses++;
 
2091
          }
 
2092
 
 
2093
          if(el->nonIPTraffic->atNetwork) {
 
2094
            char *nodeName = el->nonIPTraffic->atNodeName;
 
2095
 
 
2096
            if(numAddresses > 0) sendString("/");
 
2097
            if(nodeName == NULL) nodeName = "";
 
2098
 
 
2099
            if(snprintf(buf, sizeof(buf), "%s&nbsp;%s&nbsp;",
 
2100
                        getOSFlag(el, "Mac", 0, osBuf, sizeof(osBuf)), nodeName) < 0)
 
2101
              BufferTooShort();
 
2102
            sendString(buf);
 
2103
 
 
2104
            if(el->nonIPTraffic->atNodeType[0] != NULL) {
 
2105
              sendString("(");
 
2106
              for(i=0; i<MAX_NODE_TYPES; i++)
 
2107
                if(el->nonIPTraffic->atNodeType[i] == NULL)
 
2108
                  break;
 
2109
                else {
 
2110
                  if(i > 0) sendString("/");
 
2111
                  sendString(el->nonIPTraffic->atNodeType[i]);
 
2112
                }
 
2113
 
 
2114
              sendString(")&nbsp;");
 
2115
            }
 
2116
 
 
2117
            if(snprintf(buf, sizeof(buf), "[%d.%d]",
 
2118
                        el->nonIPTraffic->atNetwork, el->nonIPTraffic->atNode) < 0)
 
2119
              BufferTooShort();
 
2120
            sendString(buf);
 
2121
            numAddresses++;
 
2122
          }
 
2123
 
 
2124
          if(el->nonIPTraffic->ipxHostName) {
 
2125
            int numSap=0;
 
2126
 
 
2127
            if(numAddresses > 0) sendString("/");
 
2128
            if(snprintf(buf, sizeof(buf), "%s&nbsp;%s&nbsp;",
 
2129
                        getOSFlag(el, "Novell", 0, osBuf, sizeof(osBuf)),
 
2130
                        el->nonIPTraffic->ipxHostName) < 0)
 
2131
              BufferTooShort();
 
2132
            sendString(buf);
 
2133
 
 
2134
            for(i=0; i<el->nonIPTraffic->numIpxNodeTypes; i++) {
 
2135
              char *str = getSAPInfo(el->nonIPTraffic->ipxNodeType[i], 1);
 
2136
 
 
2137
              if(str[0] != '\0') {
 
2138
                if(numSap == 0)
 
2139
                  sendString("[");
 
2140
                else
 
2141
                  sendString("/");
 
2142
 
 
2143
                sendString(str);
 
2144
                numSap++;
 
2145
              }
 
2146
            }
 
2147
 
 
2148
            if(numSap > 0) sendString("]");
 
2149
 
 
2150
            numAddresses++;
 
2151
          }
 
2152
        }
 
2153
 
 
2154
        sendString("&nbsp;</TD>");
 
2155
        printBar(buf, sizeof(buf), el->actBandwidthUsageS, el->actBandwidthUsageR, maxBandwidthUsage, 3);
 
2156
 
 
2157
        if(!myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
 
2158
          if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT NOWRAP>%s</TD>", tmpName2) < 0)
 
2159
            BufferTooShort();
 
2160
          sendString(buf);
 
2161
        }
 
2162
 
 
2163
        {
 
2164
          char shortBuf[8];
 
2165
 
 
2166
          if(!subnetPseudoLocalHost(el)) {
 
2167
            i = guessHops(el);
 
2168
          } else
 
2169
            i = 0;
 
2170
 
 
2171
          sprintf(shortBuf, "%d", i % 256);
 
2172
 
 
2173
          if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>&nbsp;%s</TD>",
 
2174
                      (i == 0) ? "" : shortBuf) < 0)
 
2175
            BufferTooShort();
 
2176
          sendString(buf);
 
2177
        }
 
2178
 
 
2179
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%lu</TD>",
 
2180
                    (unsigned long)(el->totContactedSentPeers+el->totContactedRcvdPeers)) < 0)
 
2181
          BufferTooShort();
 
2182
        sendString(buf);
 
2183
 
 
2184
#if 0
 
2185
        /* Time distance */
 
2186
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s-",
 
2187
                    formatLatency(el->minLatency, FLAG_STATE_ACTIVE)) < 0)
 
2188
          BufferTooShort();
 
2189
        sendString(buf);
 
2190
 
 
2191
        if(snprintf(buf, sizeof(buf), "%s</TD>",
 
2192
                    formatLatency(el->maxLatency, FLAG_STATE_ACTIVE)) < 0)
 
2193
          BufferTooShort();
 
2194
        sendString(buf);
 
2195
#endif
 
2196
 
 
2197
        if(snprintf(buf, sizeof(buf), "<td "TD_BG" align=\"right\" nowrap>%s</td>",
 
2198
                    formatSeconds(el->lastSeen - el->firstSeen, formatBuf, sizeof(formatBuf))) < 0)
 
2199
          BufferTooShort();
 
2200
        sendString(buf);
 
2201
        
 
2202
        if(el->hostAS == 0) {
 
2203
          sendString("<TD "TD_BG" ALIGN=RIGHT NOWRAP>&nbsp;</TD>");
 
2204
        } else {
 
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>"
 
2208
                      "</TD>",
 
2209
                      el->hostAS, el->hostAS) < 0)
 
2210
            BufferTooShort();
 
2211
          sendString(buf);
 
2212
        }
 
2213
 
 
2214
        sendString("</TR>\n");
 
2215
        printedEntries++;
 
2216
        
 
2217
 
 
2218
        /* Avoid huge tables */
 
2219
        if(printedEntries > myGlobals.maxNumLines)
 
2220
          break;
 
2221
      } else {
 
2222
        traceEvent(CONST_TRACE_WARNING, "qsort() problem!");
 
2223
      }
 
2224
    }
 
2225
 
 
2226
    sendString("</TABLE>"TABLE_OFF"<P>\n");
 
2227
    sendString("</CENTER>\n");
 
2228
 
 
2229
    printFooterHostLink();
 
2230
 
 
2231
    printBandwidthFooter();   
 
2232
 
 
2233
    addPageIndicator(CONST_HOSTS_INFO_HTML, pageNum, numEntries, myGlobals.maxNumLines,
 
2234
                     revertOrder, abs(sortedColumn));
 
2235
  }
 
2236
 
 
2237
  free(tmpTable);
 
2238
}
 
2239
 
 
2240
/* ************************************ */
 
2241
 
 
2242
void printAllSessionsHTML (char* host, int actualDeviceId, int sortedColumn,
 
2243
                           int revertOrder, int pageNum, char *url,
 
2244
                           int hostInfoPage) {
 
2245
  u_int idx, i;
 
2246
  HostTraffic *el=NULL;
 
2247
  char buf[LEN_GENERAL_WORK_BUFFER];
 
2248
  char formatBuf[32], portBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
 
2249
  u_short found = 0,
 
2250
          foundFcHost = 0,
 
2251
          vsanId = 0;
 
2252
  char *tok;
 
2253
 
 
2254
  if ((tok = strchr (host, '-')) != NULL) {
 
2255
      vsanId = atoi (&tok[1]);
 
2256
      *tok = '\0';
 
2257
  }
 
2258
  
 
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)) {
 
2263
          found = 1;
 
2264
          break;
 
2265
      }
 
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))) {
 
2269
          found = 1;
 
2270
          foundFcHost = 1;
 
2271
          break;
 
2272
      }
 
2273
  }
 
2274
  /* Dennis Schoen (dennis@cns.dnsalias.org)
 
2275
   *
 
2276
   * send 404 if we cannot generate the requested page
 
2277
   */
 
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>"
 
2284
                "<p>&nbsp;</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",
 
2289
                host) < 0)
 
2290
      BufferTooShort();
 
2291
    returnHTTPpageNotFound(errorAdditionalText);
 
2292
    return;
 
2293
  } else
 
2294
    sendHTTPHeader(FLAG_HTTP_TYPE_HTML, 0, 1);
 
2295
 
 
2296
  /* ************************************ */
 
2297
 
 
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);
 
2306
  }
 
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);
 
2314
          break;
 
2315
      case showHostLunStats:
 
2316
          if (el->devType != SCSI_DEV_INITIATOR) {
 
2317
              printScsiLunStats (el, actualDeviceId, sortedColumn,
 
2318
                                 revertOrder, pageNum, url);
 
2319
          }
 
2320
          break;
 
2321
      case showHostLunGraphs:
 
2322
          if (el->devType != SCSI_DEV_INITIATOR) {
 
2323
              printScsiLunGraphs (el, actualDeviceId);
 
2324
          }
 
2325
          break;
 
2326
      case showHostScsiSessionBytes:
 
2327
          printScsiSessionBytes (actualDeviceId, sortedColumn, revertOrder,
 
2328
                                 pageNum, url, el);
 
2329
          break;
 
2330
      case showHostScsiSessionTimes:
 
2331
          printScsiSessionTimes (actualDeviceId, sortedColumn, revertOrder,
 
2332
                                 pageNum, url, el);
 
2333
          break;
 
2334
      case showHostScsiSessionStatus:
 
2335
          printScsiSessionStatusInfo (actualDeviceId, sortedColumn,
 
2336
                                      revertOrder, pageNum, url, el);
 
2337
          break;
 
2338
      case showHostScsiSessionTMInfo:
 
2339
          printScsiSessionTmInfo (actualDeviceId, sortedColumn,
 
2340
                                  revertOrder, pageNum, url, el);
 
2341
          break;
 
2342
      case showHostFcSessions:
 
2343
          printFCSessions (actualDeviceId, sortedColumn,
 
2344
                           revertOrder, pageNum, url, el);
 
2345
          break;
 
2346
      }
 
2347
      
 
2348
      
 
2349
      return;
 
2350
  }
 
2351
 
 
2352
  /* ***************************************************** */
 
2353
 
 
2354
  i = 0;
 
2355
 
 
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;
 
2362
 
 
2363
        if(i == 0) {
 
2364
          printSectionTitle("TCP/UDP&nbsp;Service/Port&nbsp;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&nbsp;Service</TH>"
 
2368
                     "<TH "TH_BG">Port</TH>"
 
2369
                     "<TH "TH_BG">#&nbsp;Client&nbsp;Sess.</TH>"
 
2370
                     "<TH "TH_BG">Last&nbsp;Client&nbsp;Peer</TH>"
 
2371
                     "<TH "TH_BG">#&nbsp;Server&nbsp;Sess.</TH>"
 
2372
                     "<TH "TH_BG">Last&nbsp;Server&nbsp;Peer</TH>"
 
2373
                     "</TR>\n");
 
2374
          i++;
 
2375
        }
 
2376
 
 
2377
        if(svc != NULL) {
 
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)
 
2380
            BufferTooShort();
 
2381
        } else {
 
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)
 
2384
            BufferTooShort();
 
2385
        }
 
2386
 
 
2387
        sendString(buf);
 
2388
 
 
2389
        if(el->portsUsage[idx]->clientUses > 0) {
 
2390
          /* Fix below courtesy of Andreas Pfaller <apfaller@yahoo.com.au> */
 
2391
          HostTraffic tmpEl;
 
2392
 
 
2393
          if(emptySerial(&el->portsUsage[idx]->clientUsesLastPeer))
 
2394
            peerHost = NULL;
 
2395
          else
 
2396
            peerHost = quickHostLink(el->portsUsage[idx]->clientUsesLastPeer, actualDeviceId, &tmpEl);
 
2397
 
 
2398
          if(peerHost == NULL) {
 
2399
            /* Courtesy of Roberto De Luca <deluca@tandar.cnea.gov.ar> */
 
2400
            strncpy(webHostName, "&nbsp;", sizeof(webHostName));
 
2401
          } else
 
2402
            strncpy(webHostName, makeHostLink(peerHost, FLAG_HOSTLINK_TEXT_FORMAT, 0, 
 
2403
                                              0, hostLinkBuf, sizeof(hostLinkBuf)),
 
2404
                    sizeof(webHostName));
 
2405
 
 
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();
 
2411
          sendString(buf);
 
2412
        } else
 
2413
          sendString("<TD "TD_BG">&nbsp;</TD><TD "TD_BG">&nbsp;</TD>");
 
2414
 
 
2415
        if(el->portsUsage[idx]->serverUses > 0) {
 
2416
          HostTraffic tmpEl;
 
2417
 
 
2418
          if(emptySerial(&el->portsUsage[idx]->serverUsesLastPeer))
 
2419
            peerHost = NULL;
 
2420
          else
 
2421
            peerHost = quickHostLink(el->portsUsage[idx]->serverUsesLastPeer, actualDeviceId, &tmpEl);
 
2422
 
 
2423
          if(peerHost == NULL) {
 
2424
            /* Courtesy of Roberto De Luca <deluca@tandar.cnea.gov.ar> */
 
2425
            strncpy(webHostName, "&nbsp;", sizeof(webHostName));
 
2426
          } else
 
2427
            strncpy(webHostName, makeHostLink(peerHost, FLAG_HOSTLINK_TEXT_FORMAT, 0, 
 
2428
                                              0, hostLinkBuf, sizeof(hostLinkBuf)), sizeof(webHostName));
 
2429
 
 
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();
 
2435
          sendString(buf);
 
2436
        } else
 
2437
          sendString("<TD "TD_BG">&nbsp;</TD><TD "TD_BG">&nbsp;</TD></TR>");
 
2438
      }
 
2439
    }
 
2440
  }
 
2441
 
 
2442
  if(i > 0){
 
2443
    sendString("</TABLE>"TABLE_OFF"<P>\n");
 
2444
    sendString("</CENTER>\n");
 
2445
  }
 
2446
  
 
2447
  /* *********************************
 
2448
     ********************************* */
 
2449
 
 
2450
  if((el->otherIpPortsRcvd[MAX_NUM_RECENT_PORTS-1] >= 0) || (el->otherIpPortsSent[MAX_NUM_RECENT_PORTS-1] >= 0)) {
 
2451
    /* We have something to show */
 
2452
    int numPrinted;
 
2453
 
 
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>"
 
2458
               "</TR>\n");
 
2459
 
 
2460
    sendString("<TR "TR_ON"><TD "TD_BG" ALIGN=LEFT><UL>");
 
2461
 
 
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)
 
2467
          BufferTooShort();
 
2468
        sendString(buf);
 
2469
        numPrinted++;
 
2470
      }
 
2471
    }
 
2472
 
 
2473
    if(numPrinted == 0) sendString("&nbsp;");
 
2474
    sendString("</UL></TD><TD "TD_BG" ALIGN=LEFT><UL>");
 
2475
 
 
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)
 
2481
          BufferTooShort();
 
2482
        sendString(buf);
 
2483
        numPrinted++;
 
2484
      }
 
2485
    }
 
2486
 
 
2487
    if(numPrinted == 0) sendString("&nbsp;");
 
2488
    sendString("</UL></TR></TABLE>"TABLE_OFF"</CENTER>");
 
2489
  }
 
2490
 
 
2491
  /* ****************************************************************** */
 
2492
 
 
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 */
 
2496
    int numPrinted;
 
2497
 
 
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>"
 
2502
               "</TR>\n");
 
2503
 
 
2504
    sendString("<TR "TR_ON"><TD "TD_BG" ALIGN=LEFT><UL>");
 
2505
 
 
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)
 
2511
          BufferTooShort();
 
2512
        sendString(buf);
 
2513
        numPrinted++;
 
2514
      }
 
2515
    }
 
2516
 
 
2517
    if(numPrinted == 0) sendString("&nbsp;");
 
2518
 
 
2519
    sendString("</UL></TD><TD "TD_BG" ALIGN=LEFT><UL>");
 
2520
 
 
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)
 
2526
          BufferTooShort();
 
2527
        sendString(buf);
 
2528
        numPrinted++;
 
2529
      }
 
2530
    }
 
2531
 
 
2532
    if(numPrinted == 0) sendString("&nbsp;");
 
2533
    sendString("</UL></TR></TABLE>"TABLE_OFF"</CENTER>");
 
2534
  }
 
2535
 
 
2536
  /* *************************************************** */
 
2537
 
 
2538
  if((el->protocolInfo != NULL)
 
2539
     && (el->protocolInfo->fileList != NULL)) {
 
2540
    FileList *list = el->protocolInfo->fileList;
 
2541
 
 
2542
    printSectionTitle("P2P Recently Exchanged Files\n");
 
2543
 
 
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");
 
2548
 
 
2549
    while(list != NULL) {
 
2550
      if(snprintf(buf, sizeof(buf), "<li>%s&nbsp",
 
2551
                  list->fileName) < 0)
 
2552
        BufferTooShort();
 
2553
      sendString(buf);
 
2554
 
 
2555
      if(FD_ISSET(BITFLAG_P2P_UPLOAD_MODE, &list->fileFlags))   sendString("<IMG SRC=/upload.gif ALT=Upload VALIGN=MIDDLE>&nbsp;");
 
2556
      if(FD_ISSET(BITFLAG_P2P_DOWNLOAD_MODE, &list->fileFlags)) sendString("<IMG SRC=/download.gif ALT=Download VALIGN=MIDDLE>&nbsp;");
 
2557
 
 
2558
      list = list->next;
 
2559
    }
 
2560
 
 
2561
    sendString("\n</ol></TD></TR></TABLE></CENTER>\n");
 
2562
  }
 
2563
 
 
2564
  /* *************************************************** */
 
2565
 
 
2566
  printHostSessions(el, actualDeviceId);
 
2567
}
 
2568
 
 
2569
/* ************************************ */
 
2570
 
 
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];
 
2576
 
 
2577
  printHTMLheader("Local Subnet Routers", NULL, 0);
 
2578
 
 
2579
  if(myGlobals.dontTrustMACaddr) {
 
2580
    printNotAvailable("-o or --no-mac");
 
2581
    return;
 
2582
  }
 
2583
 
 
2584
  for(el=getFirstHost(actualDeviceId);
 
2585
      el != NULL; el = getNextHost(actualDeviceId, el)) {
 
2586
    if(subnetLocalHost(el)) {
 
2587
 
 
2588
      for(j=0; j<MAX_NUM_CONTACTED_PEERS; j++)
 
2589
        if(!emptySerial(&el->contactedRouters.peersSerials[j])) {
 
2590
          short found = 0;
 
2591
 
 
2592
          for(i=0; i<numEntries; i++) {
 
2593
            if(cmpSerial(&el->contactedRouters.peersSerials[j], &routerList[i])) {
 
2594
              found = 1;
 
2595
              break;
 
2596
            }
 
2597
          }
 
2598
 
 
2599
          if((found == 0) && (numEntries < MAX_NUM_ROUTERS)) {
 
2600
            routerList[numEntries++] = el->contactedRouters.peersSerials[j];
 
2601
          }
 
2602
        }
 
2603
    }
 
2604
  } /* for */
 
2605
 
 
2606
  if(numEntries == 0) {
 
2607
    printNoDataYet();
 
2608
    return;
 
2609
  } else {
 
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");
 
2613
 
 
2614
    for(i=0; i<numEntries; i++) {
 
2615
      HostTraffic tmpEl;
 
2616
 
 
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",
 
2619
                    getRowColor(),
 
2620
                    makeHostLink(router, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, 
 
2621
                                 hostLinkBuf, sizeof(hostLinkBuf))) < 0) BufferTooShort();
 
2622
        sendString(buf);
 
2623
 
 
2624
 
 
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)
 
2633
                  BufferTooShort();
 
2634
                sendString(buf);
 
2635
                break;
 
2636
              }
 
2637
          }
 
2638
        }
 
2639
 
 
2640
        sendString("</OL></TD></TR>\n");
 
2641
      }
 
2642
    }
 
2643
 
 
2644
    sendString("</TABLE>"TABLE_OFF"\n");
 
2645
    sendString("</CENTER>\n");
 
2646
 
 
2647
    printHostColorCode(FALSE, 0);
 
2648
 
 
2649
    printFooterHostLink();
 
2650
  }
 
2651
}
 
2652
 
 
2653
/* ************************************ */
 
2654
 
 
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];
 
2667
 
 
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";
 
2672
    break;
 
2673
  case FLAG_REMOTE_TO_REMOTE_ACCOUNTING:
 
2674
    str = CONST_IP_R_2_R_HTML;
 
2675
    title = "Remote to Remote IP Traffic";
 
2676
    break;
 
2677
  case FLAG_LOCAL_TO_REMOTE_ACCOUNTING:
 
2678
    str = CONST_IP_L_2_R_HTML;
 
2679
    title = "Local to Remote IP Traffic";
 
2680
    break;
 
2681
  case FLAG_LOCAL_TO_LOCAL_ACCOUNTING:
 
2682
    str = CONST_IP_L_2_L_HTML;
 
2683
    title = "Local IP Traffic";
 
2684
    break;
 
2685
  }
 
2686
 
 
2687
  printHTMLheader(title, NULL, 0);
 
2688
 
 
2689
  if(revertOrder) {
 
2690
    sign = "";
 
2691
    arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
2692
  } else {
 
2693
    sign = "-";
 
2694
    arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
2695
  }
 
2696
 
 
2697
  totalBytesSent=0, totalBytesRcvd=0;
 
2698
  maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
 
2699
 
 
2700
  tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "printIpAccounting");
 
2701
  if(tmpTable == NULL)
 
2702
      return;
 
2703
 
 
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;
 
2718
          }
 
2719
        }
 
2720
        break;
 
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;
 
2727
          }
 
2728
        }
 
2729
        break;
 
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;
 
2736
          }
 
2737
        }
 
2738
        break;
 
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;
 
2745
          }
 
2746
        }
 
2747
        break;
 
2748
      }
 
2749
 
 
2750
      if(numEntries >= maxHosts) break;
 
2751
    }
 
2752
  }
 
2753
 
 
2754
  if(numEntries > 0) {
 
2755
    int i;
 
2756
 
 
2757
    myGlobals.columnSort = sortedColumn;
 
2758
    myGlobals.sortFilter = remoteToLocal;
 
2759
    qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpHostsFctn);
 
2760
 
 
2761
    if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", str, sign) < 0)
 
2762
      BufferTooShort();
 
2763
    if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", str) < 0)
 
2764
      BufferTooShort();
 
2765
 
 
2766
    for(i=1; i<=4; i++)
 
2767
      if(abs(myGlobals.columnSort) == i)
 
2768
        arrow[i] = arrowGif, theAnchor[i] = htmlAnchor;
 
2769
      else
 
2770
        arrow[i] = "", theAnchor[i] = htmlAnchor1;
 
2771
 
 
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&nbsp;Address%s</A></TH>\n"
 
2777
                "<TH "TH_BG" COLSPAN=2>%s3>Data&nbsp;Sent%s</A></TH>"
 
2778
                "<TH "TH_BG" COLSPAN=2>%s4>Data&nbsp;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)
 
2782
      BufferTooShort();
 
2783
 
 
2784
    sendString(buf);
 
2785
 
 
2786
    for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
2787
      if(revertOrder)
 
2788
        el = tmpTable[numEntries-idx-1];
 
2789
      else
 
2790
        el = tmpTable[idx];
 
2791
 
 
2792
      if(el != NULL) {
 
2793
        char *tmpName1;
 
2794
        tmpName1 = el->hostNumIpAddress;
 
2795
        if((tmpName1[0] == '\0') || (strcmp(tmpName1, "0.0.0.0") == 0))
 
2796
          tmpName1 = myGlobals.separator;
 
2797
 
 
2798
        switch(remoteToLocal) {
 
2799
        case FLAG_REMOTE_TO_LOCAL_ACCOUNTING:
 
2800
          a = el->bytesSentLoc.value;
 
2801
          b = el->bytesRcvdLoc.value;
 
2802
          break;
 
2803
        case FLAG_REMOTE_TO_REMOTE_ACCOUNTING:
 
2804
          a = el->bytesSentRem.value;
 
2805
          b = el->bytesRcvdFromRem.value;
 
2806
          break;
 
2807
        case FLAG_LOCAL_TO_REMOTE_ACCOUNTING:
 
2808
          a = el->bytesSentRem.value;
 
2809
          b = el->bytesRcvdFromRem.value;
 
2810
          break;
 
2811
        case FLAG_LOCAL_TO_LOCAL_ACCOUNTING:
 
2812
          a = el->bytesSentLoc.value;
 
2813
          b = el->bytesRcvdLoc.value;
 
2814
          break;
 
2815
        }
 
2816
 
 
2817
        if(a < 100)  /* Avoid very small decimal values */
 
2818
          sentpct = 0;
 
2819
        else
 
2820
          sentpct = (100*(float)a)/totalBytesSent;
 
2821
 
 
2822
        if(b < 100)  /* Avoid very small decimal values */
 
2823
          rcvdpct = 0;
 
2824
        else
 
2825
          rcvdpct = (100*(float)b)/totalBytesRcvd;
 
2826
 
 
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",
 
2831
                    getRowColor(),
 
2832
                    makeHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
 
2833
                    tmpName1,
 
2834
                    formatBytes(a, 1, formatBuf, sizeof(formatBuf)),
 
2835
                    sentpct, myGlobals.separator,
 
2836
                    formatBytes(b, 1, formatBuf1, sizeof(formatBuf1)),
 
2837
                    rcvdpct, myGlobals.separator) < 0)
 
2838
          BufferTooShort();
 
2839
        sendString(buf);
 
2840
 
 
2841
        /* Avoid huge tables */
 
2842
        if(printedEntries++ > myGlobals.maxNumLines)
 
2843
          break;
 
2844
      }
 
2845
    }
 
2846
 
 
2847
    sendString("</TABLE>"TABLE_OFF"\n");
 
2848
 
 
2849
    addPageIndicator(str, pageNum, numEntries, myGlobals.maxNumLines,
 
2850
                     revertOrder, abs(sortedColumn));
 
2851
 
 
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");
 
2855
 
 
2856
    totalBytes = totalBytesSent+totalBytesRcvd;
 
2857
 
 
2858
    /* In this case the total traffic is just half and
 
2859
       the following statement holds:
 
2860
       totalBytesSent == totalBytesRcvd
 
2861
 
 
2862
       Courtesy of Jac Engel <jacengel@home.nl>
 
2863
    */
 
2864
    if(remoteToLocal == FLAG_LOCAL_TO_LOCAL_ACCOUNTING)
 
2865
      totalBytes /= 2;
 
2866
 
 
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)
 
2876
      BufferTooShort();
 
2877
 
 
2878
    sendString(buf);
 
2879
    sendString("</TABLE>"TABLE_OFF"\n");
 
2880
    sendString("</CENTER>\n");
 
2881
 
 
2882
    printFooterHostLink();
 
2883
 
 
2884
  } else
 
2885
    printNoDataYet();
 
2886
 
 
2887
  free(tmpTable);
 
2888
}
 
2889
 
 
2890
/* ********************************** */
 
2891
 
 
2892
void printActiveTCPSessions(int actualDeviceId, int pageNum, HostTraffic *el) {
 
2893
  int idx;
 
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];
 
2899
 
 
2900
  if(!myGlobals.enableSessionHandling) {
 
2901
    printNotAvailable("-z or --disable-sessions");
 
2902
    return;
 
2903
  }
 
2904
 
 
2905
  if((myGlobals.device[actualDeviceId].tcpSession == NULL) ||
 
2906
     (myGlobals.device[actualDeviceId].numTcpSessions == 0)) {
 
2907
     printNoDataYet();
 
2908
     return;
 
2909
  }
 
2910
 
 
2911
  /*
 
2912
    Due to the way sessions are handled, sessions before those to
 
2913
    display need to be skipped
 
2914
  */
 
2915
 
 
2916
  for(idx=1, numSessions=0, printedSessions=0; idx<MAX_TOT_NUM_SESSIONS; idx++) {
 
2917
 
 
2918
    if(el && (printedSessions >= el->numHostSessions)) break;
 
2919
 
 
2920
#ifdef CFG_MULTITHREADED
 
2921
    accessMutex(&myGlobals.tcpSessionsMutex, "printActiveTCPSessions");
 
2922
#endif
 
2923
 
 
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];
 
2928
 
 
2929
      while((session != NULL) && (printedSessions < myGlobals.maxNumLines)) {
 
2930
#ifndef PARM_PRINT_ALL_SESSIONS
 
2931
        if(session->sessionState != FLAG_STATE_ACTIVE) {
 
2932
          session = session->next;
 
2933
          continue;
 
2934
        }
 
2935
#endif
 
2936
 
 
2937
        if(el && (session->initiator  != el) && (session->remotePeer != el)) {
 
2938
          session = session->next;
 
2939
          continue;
 
2940
        }
 
2941
 
 
2942
        if((numSessions++) < pageNum*myGlobals.maxNumLines) {
 
2943
          session = session->next;
 
2944
          continue;
 
2945
        }
 
2946
 
 
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&nbsp;Sent</TH>"
 
2954
                     "<TH "TH_BG">Data&nbsp;Rcvd</TH>"
 
2955
                     "<TH "TH_BG">Active&nbsp;Since</TH>"
 
2956
                     "<TH "TH_BG">Last&nbsp;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>"
 
2962
#endif
 
2963
                     "</TR>\n");
 
2964
        }
 
2965
 
 
2966
        sport = getPortByNum(session->sport, IPPROTO_TCP);
 
2967
        dport = getPortByNum(session->dport, IPPROTO_TCP);
 
2968
        dataSent = session->bytesSent.value;
 
2969
        dataRcvd = session->bytesRcvd.value;
 
2970
 
 
2971
        if(sport == NULL) {
 
2972
          static char _sport[8];
 
2973
          if(snprintf(_sport, 8, "%d", session->sport) < 0)
 
2974
            BufferTooShort();
 
2975
          sport = _sport;
 
2976
        }
 
2977
 
 
2978
        if(dport == NULL) {
 
2979
          static char _dport[8];
 
2980
          if(snprintf(_dport, 8, "%d", session->dport) < 0)
 
2981
            BufferTooShort();
 
2982
          dport = _dport;
 
2983
        }
 
2984
 
 
2985
        /* Sanity check */
 
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;
 
2992
 
 
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>"
 
3005
#endif
 
3006
                    "</TR>\n",
 
3007
                    getRowColor(),
 
3008
                    makeHostLink(session->initiator, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)),
 
3009
                    sport,
 
3010
                    session->isP2P == 1 ? "&nbsp&lt;P2P&gt;" : "",
 
3011
                    makeHostLink(session->remotePeer, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf1, sizeof(hostLinkBuf1)),
 
3012
                    dport,
 
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)
 
3022
#endif
 
3023
                    ) < 0) BufferTooShort();
 
3024
 
 
3025
        sendString(buf);
 
3026
        session = session->next;
 
3027
        printedSessions++;
 
3028
      }
 
3029
    }
 
3030
#ifdef CFG_MULTITHREADED
 
3031
    releaseMutex(&myGlobals.tcpSessionsMutex);
 
3032
#endif
 
3033
  }
 
3034
 
 
3035
  if(printedSessions > 0) {
 
3036
    sendString("</TABLE>"TABLE_OFF"<P>\n");
 
3037
    sendString("</CENTER>\n");
 
3038
 
 
3039
    if(el == NULL)
 
3040
      addPageIndicator(CONST_ACTIVE_TCP_SESSIONS_HTML, pageNum,
 
3041
                       myGlobals.device[actualDeviceId].numTcpSessions,
 
3042
                       myGlobals.maxNumLines, -1, 0);
 
3043
 
 
3044
    printHostColorCode(FALSE, 0);
 
3045
 
 
3046
    printFooterHostLink();
 
3047
  } else {
 
3048
    if(el == NULL) {
 
3049
      printHTMLheader("Active TCP Sessions", NULL, 0);
 
3050
      printFlagedWarning("<I>No Active TCP Sessions</I>");
 
3051
    }
 
3052
  }
 
3053
}
 
3054
 
 
3055
 
 
3056
/* ********************************** */
 
3057
 
 
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];
 
3063
  int portBufLen;
 
3064
  
 
3065
  printHTMLheader("TCP/UDP: Local Protocol Usage", NULL, 0);
 
3066
 
 
3067
  memset(clientPorts, 0, sizeof(clientPorts));
 
3068
  memset(serverPorts, 0, sizeof(serverPorts));
 
3069
 
 
3070
  hosts = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].hostsno*sizeof(HostTraffic*), "printIpProtocolUsage");
 
3071
  if(hosts == NULL)
 
3072
      return;
 
3073
 
 
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;
 
3078
 
 
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;
 
3084
            numPorts++;
 
3085
          }
 
3086
        }
 
3087
      }
 
3088
    }
 
3089
 
 
3090
    if(hostsNum >= maxHosts) break;
 
3091
  } /* for */
 
3092
 
 
3093
  if(numPorts == 0) {
 
3094
    printNoDataYet();
 
3095
    free(hosts);
 
3096
    return;
 
3097
  }
 
3098
 
 
3099
  /* Hosts are now in a contiguous structure (hosts[])... */
 
3100
 
 
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");
 
3104
 
 
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();
 
3110
      sendString(buf);
 
3111
 
 
3112
      if(clientPorts[j] > 0) {
 
3113
        sendString("<UL>");
 
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)
 
3120
              BufferTooShort();
 
3121
            sendString(buf);
 
3122
          }
 
3123
        sendString("</UL>");
 
3124
      } else
 
3125
        sendString("&nbsp;");
 
3126
 
 
3127
      sendString("</TD><TD "TD_BG">");
 
3128
 
 
3129
      if(serverPorts[j] > 0) {
 
3130
        sendString("<UL>");
 
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)
 
3137
              BufferTooShort();
 
3138
            sendString(buf);
 
3139
          }
 
3140
        sendString("</UL>");
 
3141
      } else
 
3142
        sendString("&nbsp;");
 
3143
 
 
3144
      sendString("</TD></TR>");
 
3145
    } /* for */
 
3146
 
 
3147
  sendString("</TABLE>"TABLE_OFF"<P>\n");
 
3148
  sendString("</CENTER>\n");
 
3149
 
 
3150
  printHostColorCode(FALSE, 0);
 
3151
 
 
3152
  printFooterHostLink();
 
3153
 
 
3154
  free(hosts);
 
3155
}
 
3156
 
 
3157
/* ********************************** */
 
3158
 
 
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) {
 
3164
 
 
3165
  /* This shouldn't happen */
 
3166
  if(maxPercentage > 100) { maxPercentage = 100; }
 
3167
 
 
3168
  if(percentageR == FLAG_NONSPLITBAR) {
 
3169
    /* Single bar */
 
3170
    if(percentageS > maxPercentage) { percentageS = maxPercentage; }
 
3171
 
 
3172
    switch(percentageS) {
 
3173
      case 0:
 
3174
        if(snprintf(buf, bufLen, "<TD "TD_BG" %s>&nbsp;</TD>\n", getActualRowColor()) < 0)
 
3175
          BufferTooShort();
 
3176
        break;
 
3177
      default:
 
3178
        if(snprintf(buf, bufLen,
 
3179
                    "<TD "TD_BG" ALIGN=LEFT>"
 
3180
                    "<IMG ALIGN=ABSMIDDLE SRC=\"/gauge.jpg\" ALT=\"%d%%\" WIDTH=%d HEIGHT=12>"
 
3181
                    "&nbsp;</TD>\n",
 
3182
                    percentageS, ratio*percentageS) < 0)
 
3183
          BufferTooShort();
 
3184
        break;
 
3185
    }
 
3186
  } else {
 
3187
    /* Could happen because of rounding */
 
3188
    if((percentageS+percentageR) > maxPercentage) 
 
3189
      percentageR--;
 
3190
    if((percentageS+percentageR) > maxPercentage) 
 
3191
      percentageS--;
 
3192
 
 
3193
    switch(percentageS+percentageR) {
 
3194
      case 0:
 
3195
        if(snprintf(buf, bufLen, "<TD "TD_BG" %s>&nbsp;</TD>\n", getActualRowColor()) < 0)
 
3196
          BufferTooShort();
 
3197
        break;
 
3198
      default:
 
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>"
 
3203
                    "&nbsp;</TD>\n",
 
3204
                    percentageS, ratio*percentageS, percentageR, ratio*percentageR) < 0)
 
3205
          BufferTooShort();
 
3206
        break;
 
3207
    }
 
3208
  }
 
3209
 
 
3210
  sendString(buf);
 
3211
}
 
3212
 
 
3213
/* ********************************** */
 
3214
 
 
3215
static int cmpPortsFctn(const void *_a, const void *_b) {
 
3216
  if((_a == NULL) || (_b == NULL))
 
3217
    return(0);
 
3218
  else {
 
3219
    PortCounter *a, *b;
 
3220
 
 
3221
    a = *((PortCounter**)_a);
 
3222
    b = *((PortCounter**)_b);
 
3223
 
 
3224
    if((a == NULL) || (b == NULL))
 
3225
       return(0);
 
3226
 
 
3227
    if((a->sent+a->rcvd) > (b->sent+b->rcvd))
 
3228
      return(-1);
 
3229
    else
 
3230
      return(1);
 
3231
  }
 
3232
}
 
3233
 
 
3234
/* ********************************** */
 
3235
 
 
3236
void printIpProtocolDistribution(int mode, int revertOrder) {
 
3237
  int i;
 
3238
  char buf[2*LEN_GENERAL_WORK_BUFFER], *sign;
 
3239
  float total, partialTotal, remainingTraffic;
 
3240
  float percentage;
 
3241
  char formatBuf[32], formatBuf1[32], formatBuf2[32];
 
3242
 
 
3243
  if(revertOrder)
 
3244
    sign = "";
 
3245
  else
 
3246
    sign = "-";
 
3247
 
 
3248
  if(mode == FLAG_HOSTLINK_TEXT_FORMAT) {
 
3249
    printSectionTitle("IP Protocol Distribution");
 
3250
 
 
3251
#ifndef EMBEDDED
 
3252
    sendString("<CENTER><IMG SRC=\"" CONST_PIE_IPPROTO_RL_DIST CHART_FORMAT "\" "
 
3253
               "alt=\"ipProtocol distribution chart\"><p>\n</CENTER>\n");
 
3254
#endif
 
3255
 
 
3256
    printSectionTitle("Local Traffic");
 
3257
 
 
3258
    total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local.value+
 
3259
                    myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.local.value)/1024;
 
3260
    if(total == 0)
 
3261
      printNoDataYet();
 
3262
    else {
 
3263
      sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
 
3264
                 "<TH "TH_BG" WIDTH=150>IP&nbsp;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;
 
3269
 
 
3270
      partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local.value/1024;
 
3271
      percentage = ((float)(partialTotal*100))/((float)total);
 
3272
      printTableEntryPercentage(buf, sizeof(buf), "TCP&nbsp;vs.&nbsp;UDP",
 
3273
                                "TCP", "UDP", total, percentage);
 
3274
 
 
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&nbsp;Protocol</TH>"
 
3278
                 "<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
 
3279
                 "Percentage</TH></TR>\n");
 
3280
 
 
3281
      for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
 
3282
        partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].local.value/1024;
 
3283
 
 
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);
 
3289
        }
 
3290
      }
 
3291
 
 
3292
      if(total > remainingTraffic)
 
3293
        remainingTraffic = total - remainingTraffic;
 
3294
      else
 
3295
        remainingTraffic = 0;
 
3296
 
 
3297
      if(remainingTraffic > 0) {
 
3298
        percentage = ((float)(remainingTraffic*100))/((float)total);
 
3299
        printTableEntry(buf, sizeof(buf), "Other&nbsp;TCP/UDP-based&nbsp;Protocols",
 
3300
                        CONST_COLOR_1, remainingTraffic, percentage);
 
3301
      }
 
3302
 
 
3303
      sendString("</TABLE>"TABLE_OFF"<P>\n");
 
3304
      sendString("</CENTER>\n");
 
3305
    }
 
3306
 
 
3307
    /* ********************************************************** */
 
3308
 
 
3309
    total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote2local.value+
 
3310
                    myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.remote2local.value)/1024;
 
3311
 
 
3312
    printSectionTitle("Remote to Local Traffic");
 
3313
 
 
3314
    if(total == 0)
 
3315
      printNoDataYet();
 
3316
    else {
 
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&nbsp;Protocol</TH>"
 
3320
                 "<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250>"
 
3321
                 "Percentage</TH></TR>\n");
 
3322
 
 
3323
      if(total == 0) total = 1; /* Avoids divisions by zero */
 
3324
      remainingTraffic = 0;
 
3325
 
 
3326
      partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote2local.value/1024;
 
3327
      percentage = ((float)(partialTotal*100))/((float)total);
 
3328
      printTableEntryPercentage(buf, sizeof(buf), "TCP&nbsp;vs.&nbsp;UDP",
 
3329
                                "TCP", "UDP", total, percentage);
 
3330
 
 
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&nbsp;Protocol</TH>"
 
3334
                 "<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
 
3335
                 "Percentage</TH></TR>\n");
 
3336
 
 
3337
      for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
 
3338
        partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].remote2local.value/1024;
 
3339
 
 
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);
 
3345
        }
 
3346
      }
 
3347
 
 
3348
      if(total > remainingTraffic)
 
3349
        remainingTraffic = total - remainingTraffic;
 
3350
      else
 
3351
        remainingTraffic = 0;
 
3352
 
 
3353
      if(remainingTraffic > 0) {
 
3354
        percentage = ((float)(remainingTraffic*100))/((float)total);
 
3355
        printTableEntry(buf, sizeof(buf), "Other&nbsp;TCP/UDP-based&nbsp;Protocols",
 
3356
                        CONST_COLOR_1, remainingTraffic, percentage);
 
3357
      }
 
3358
      sendString("</TABLE>"TABLE_OFF"\n<P>\n");
 
3359
      sendString("</CENTER>\n");
 
3360
    }
 
3361
 
 
3362
    /* ********************************************************** */
 
3363
 
 
3364
    /* Courtesy of "Burton M. Strauss III" <BStrauss3@attbi.com> */
 
3365
 
 
3366
    printSectionTitle("Remote Traffic");
 
3367
 
 
3368
    total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote.value+
 
3369
                    myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.remote.value)/1024;
 
3370
    if(total == 0)
 
3371
      printNoDataYet();
 
3372
    else {
 
3373
      sendString("<CENTER>"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=\"80%\"><TR "TR_ON" "DARK_BG">"
 
3374
                 "<TH "TH_BG" WIDTH=150>IP&nbsp;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;
 
3379
 
 
3380
      partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.remote.value/1024;
 
3381
      percentage = ((float)(partialTotal*100))/((float)total);
 
3382
      printTableEntryPercentage(buf, sizeof(buf), "TCP&nbsp;vs.&nbsp;UDP",
 
3383
                                "TCP", "UDP", total, percentage);
 
3384
 
 
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&nbsp;Protocol</TH>"
 
3388
                 "<TH "TH_BG" WIDTH=100>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
 
3389
                 "Percentage</TH></TR>\n");
 
3390
 
 
3391
      for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
 
3392
        partialTotal =
 
3393
          (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].remote.value/1024;
 
3394
 
 
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);
 
3401
        }
 
3402
      }
 
3403
 
 
3404
      if(total > remainingTraffic)
 
3405
        remainingTraffic = total - remainingTraffic;
 
3406
      else
 
3407
        remainingTraffic = 0;
 
3408
 
 
3409
      if(remainingTraffic > 0) {
 
3410
        percentage = ((float)(remainingTraffic*100))/((float)total);
 
3411
        printTableEntry(buf, sizeof(buf),
 
3412
                        "Other&nbsp;TCP/UDP-based&nbsp;Protocols",
 
3413
                        CONST_COLOR_1, remainingTraffic, percentage);
 
3414
      }
 
3415
 
 
3416
      sendString("</TABLE>"TABLE_OFF"<P>\n");
 
3417
      sendString("</CENTER>\n");
 
3418
    }
 
3419
 
 
3420
    /* ********************************************************** */
 
3421
 
 
3422
    printSectionTitle("Local to Remote Traffic");
 
3423
 
 
3424
    total = (float)(myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local2remote.value+
 
3425
                    myGlobals.device[myGlobals.actualReportDeviceId].udpGlobalTrafficStats.local2remote.value)/1024;
 
3426
    if(total == 0)
 
3427
      printNoDataYet();
 
3428
    else {
 
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&nbsp;Protocol</TH>"
 
3432
                 "<TH "TH_BG" WIDTH=100>Data</TH>"
 
3433
                 "<TH "TH_BG" WIDTH=250>Percentage</TH></TR>\n");
 
3434
 
 
3435
      if(total == 0) total = 1; /* Avoids divisions by zero */
 
3436
      remainingTraffic = 0;
 
3437
 
 
3438
      partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].tcpGlobalTrafficStats.local2remote.value/1024;
 
3439
      percentage = ((float)(partialTotal*100))/((float)total);
 
3440
      printTableEntryPercentage(buf, sizeof(buf), "TCP&nbsp;vs.&nbsp;UDP",
 
3441
                                "TCP", "UDP", total, percentage);
 
3442
 
 
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&nbsp;Protocol</TH>"
 
3446
                 "<TH "TH_BG" WIDTH=100>Data</TH>"
 
3447
                 "<TH "TH_BG" WIDTH=250 COLSPAN=2>Percentage</TH></TR>\n");
 
3448
 
 
3449
      for(i=0; i<myGlobals.numIpProtosToMonitor; i++) {
 
3450
        partialTotal = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipProtoStats[i].local2remote.value/1024;
 
3451
 
 
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);
 
3457
        }
 
3458
      }
 
3459
 
 
3460
      if(total > remainingTraffic)
 
3461
        remainingTraffic = total - remainingTraffic;
 
3462
      else
 
3463
        remainingTraffic = 0;
 
3464
 
 
3465
      if(remainingTraffic > 0) {
 
3466
        percentage = ((float)(remainingTraffic*100))/((float)total);
 
3467
        printTableEntry(buf, sizeof(buf), "Other&nbsp;IP-based&nbsp;Protocols",
 
3468
                        CONST_COLOR_1, remainingTraffic, percentage);
 
3469
      }
 
3470
      sendString("</TABLE>"TABLE_OFF"<P>\n");
 
3471
      sendString("</CENTER>\n");
 
3472
    }
 
3473
  } else {
 
3474
    total = (float)myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value;
 
3475
 
 
3476
    {
 
3477
      ProtocolsList *protoList = myGlobals.ipProtosList;
 
3478
      int idx1 = 0;
 
3479
 
 
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;
 
3483
        else
 
3484
          total = 0;
 
3485
 
 
3486
        idx1++, protoList = protoList->next;
 
3487
      }
 
3488
    }
 
3489
 
 
3490
    if(total == 0)
 
3491
      return;
 
3492
    else {
 
3493
      int numProtosFound = 0;
 
3494
 
 
3495
      printSectionTitle("Global TCP/UDP Protocol Distribution");
 
3496
 
 
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&nbsp;Protocol</TH>"
 
3500
                 "<TH "TH_BG" WIDTH=50>Data</TH><TH "TH_BG" WIDTH=250 COLSPAN=2>"
 
3501
                 "Percentage</TH></TR>\n");
 
3502
 
 
3503
      remainingTraffic = 0;
 
3504
 
 
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;
 
3510
 
 
3511
        if(partialTotal > 0) {
 
3512
          remainingTraffic += partialTotal;
 
3513
          percentage = ((float)(partialTotal*100))/((float)total);
 
3514
          numProtosFound++;
 
3515
          printTableEntry(buf, sizeof(buf), myGlobals.protoIPTrafficInfos[i],
 
3516
                          CONST_COLOR_1, partialTotal/1024, percentage);
 
3517
        }
 
3518
      }
 
3519
 
 
3520
      if(total > remainingTraffic)
 
3521
        remainingTraffic = total - remainingTraffic;
 
3522
      else
 
3523
        remainingTraffic = 0;
 
3524
 
 
3525
      if(remainingTraffic > 0) {
 
3526
        percentage = ((float)(remainingTraffic*100))/((float)total);
 
3527
        printTableEntry(buf, sizeof(buf), "Other&nbsp;TCP/UDP-based&nbsp;Protocols",
 
3528
                        CONST_COLOR_1, remainingTraffic/1024, percentage);
 
3529
      }
 
3530
 
 
3531
#ifndef EMBEDDED
 
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");
 
3536
#endif
 
3537
      sendString("</TABLE>"TABLE_OFF"<P>\n");
 
3538
 
 
3539
      /* *********************** */
 
3540
 
 
3541
      if(remainingTraffic > 0) {
 
3542
        PortCounter **ipPorts;
 
3543
        int idx = 0;
 
3544
 
 
3545
        ipPorts = (PortCounter**)calloc(MAX_IP_PORT, sizeof(PortCounter*));
 
3546
 
 
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];
 
3550
            idx++;
 
3551
          }
 
3552
        }
 
3553
 
 
3554
        if(idx > 0) {
 
3555
          printSectionTitle("TCP/UDP Traffic Port Distribution:<br>Last Minute View");
 
3556
 
 
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>");
 
3560
 
 
3561
          qsort(ipPorts, idx, sizeof(PortCounter**), cmpPortsFctn);
 
3562
 
 
3563
          if(idx > 32) idx = 32; /* Limit to 32 entries max */
 
3564
 
 
3565
          for(i=0; i<idx; i++) {
 
3566
            if(ipPorts[i] != NULL) {
 
3567
              char portBuf[32];
 
3568
              int portBufLen;
 
3569
              char *symPort = getAllPortByNum(ipPorts[i]->port, portBuf, sizeof(portBuf));
 
3570
 
 
3571
              if(symPort == NULL) symPort = "";
 
3572
 
 
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>"
 
3578
                          "</TR>\n",
 
3579
                          getRowColor(),
 
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();
 
3585
              sendString(buf);
 
3586
            }
 
3587
          } /* for */
 
3588
 
 
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");
 
3593
        }
 
3594
        free(ipPorts);
 
3595
        sendString("</TABLE>"TABLE_OFF"<P></center>\n");
 
3596
        if (idx >= 32)
 
3597
          sendString("<p>This extract is just a sample of the packets ntop has seen.</p>");
 
3598
      } else {
 
3599
        sendString("<p>Note:This report includes broadcast packets</p>\n");
 
3600
        sendString("</CENTER>\n");
 
3601
      }
 
3602
    }
 
3603
  }
 
3604
}
 
3605
 
 
3606
/* ************************ */
 
3607
 
 
3608
void printProtoTraffic(void) {
 
3609
  float total, perc;
 
3610
  char buf[LEN_GENERAL_WORK_BUFFER], formatBuf[32];
 
3611
 
 
3612
  total = myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value/1024; /* total is expressed in KBytes.value */
 
3613
 
 
3614
  if(total == 0)
 
3615
    return;
 
3616
 
 
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");
 
3621
 
 
3622
  perc = 100*((float)myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value/
 
3623
              myGlobals.device[myGlobals.actualReportDeviceId].ethernetBytes.value);
 
3624
  if(perc > 100) perc = 100;
 
3625
 
 
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%%\">",
 
3630
              getRowColor(),
 
3631
              formatBytes(myGlobals.device[myGlobals.actualReportDeviceId].ipBytes.value, 1,
 
3632
                          formatBuf, sizeof(formatBuf)),
 
3633
              perc) < 0)
 
3634
    BufferTooShort();
 
3635
  sendString(buf);
 
3636
 
 
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));
 
3649
  
 
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));
 
3654
  {
 
3655
    ProtocolsList *protoList = myGlobals.ipProtosList;
 
3656
    int idx = 0;
 
3657
 
 
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;
 
3664
    }
 
3665
  }
 
3666
 
 
3667
  printTableEntry(buf, sizeof(buf), "Other&nbsp;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));
 
3671
 
 
3672
  sendString("</TABLE>"TABLE_OFF"</TR>");
 
3673
 
 
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));
 
3710
 
 
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));
 
3715
 
 
3716
#ifndef EMBEDDED
 
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");
 
3720
#endif
 
3721
 
 
3722
  sendString("</TABLE>"TABLE_OFF"<P></CENTER>\n");
 
3723
}
 
3724
 
 
3725
/* ************************ */
 
3726
 
 
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];
 
3730
  short *activeHosts;
 
3731
  Counter minTraffic=(Counter)LONG_MAX, maxTraffic=0, avgTraffic;
 
3732
  Counter avgTrafficLow, avgTrafficHigh, tmpCounter;
 
3733
 
 
3734
  printHTMLheader("IP Subnet Traffic Matrix", NULL, 0);
 
3735
 
 
3736
  if(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix == NULL) {
 
3737
    printFlagedWarning("<I>Traffic matrix is not available for the selected network interface</I>");
 
3738
    return;
 
3739
  }
 
3740
 
 
3741
  activeHosts = (short*)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numHosts*sizeof(short), "printIpTrafficMatrix");
 
3742
  if(activeHosts == NULL)
 
3743
      return;
 
3744
 
 
3745
  for(i=0; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; i++) {
 
3746
    activeHosts[i] = 0;
 
3747
 
 
3748
    for(j=0; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; j++) {
 
3749
      int id = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
 
3750
 
 
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))) {
 
3755
        activeHosts[i] = 1;
 
3756
        numEntries++;
 
3757
        break;
 
3758
      }
 
3759
    }
 
3760
 
 
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>&nbsp;F&nbsp;"
 
3765
                   "&nbsp;&nbsp;To<br>&nbsp;r<br>&nbsp;o<br>&nbsp;m</SMALL></TH>\n");
 
3766
      }
 
3767
 
 
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)
 
3771
        BufferTooShort();
 
3772
      sendString(buf);
 
3773
    }
 
3774
  }
 
3775
 
 
3776
  if(numEntries == 0) {
 
3777
    printNoDataYet();
 
3778
    free(activeHosts);
 
3779
    return;
 
3780
  } else
 
3781
    sendString("</TR>\n");
 
3782
 
 
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;
 
3786
 
 
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;
 
3798
      }
 
3799
    }
 
3800
 
 
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 */
 
3804
 
 
3805
 
 
3806
  for(i=0; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; i++)
 
3807
    if(activeHosts[i] == 1) {
 
3808
      numConsecutiveEmptyCells=0;
 
3809
 
 
3810
      if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s><TH "TH_BG" ALIGN=LEFT "DARK_BG"><SMALL>",  getRowColor()) < 0)
 
3811
        BufferTooShort();
 
3812
      sendString(buf);
 
3813
      
 
3814
      sendString(makeHostLink(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrixHosts[i],
 
3815
                              FLAG_HOSTLINK_TEXT_FORMAT, 1, 0, hostLinkBuf, sizeof(hostLinkBuf)));
 
3816
      sendString("</SMALL></TH>");
 
3817
 
 
3818
      for(j=0; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; j++) {
 
3819
        int idx = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
 
3820
 
 
3821
        if((i == j) &&
 
3822
           strcmp(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrixHosts[i]->hostNumIpAddress,
 
3823
                  "127.0.0.1"))
 
3824
          numConsecutiveEmptyCells++;
 
3825
        else if(activeHosts[j] == 1) {
 
3826
          if(myGlobals.device[myGlobals.actualReportDeviceId].ipTrafficMatrix[idx] == NULL)
 
3827
            numConsecutiveEmptyCells++;
 
3828
          else {
 
3829
            if(numConsecutiveEmptyCells > 0) {
 
3830
              if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d>&nbsp;</TD>\n",
 
3831
                          numConsecutiveEmptyCells) < 0) BufferTooShort();
 
3832
              sendString(buf);
 
3833
              numConsecutiveEmptyCells = 0;
 
3834
            }
 
3835
 
 
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)
 
3846
              BufferTooShort();
 
3847
            sendString(buf);
 
3848
          }
 
3849
        }
 
3850
      }
 
3851
 
 
3852
      if(numConsecutiveEmptyCells > 0) {
 
3853
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d>&nbsp;</TD>\n",
 
3854
                    numConsecutiveEmptyCells) < 0)
 
3855
          BufferTooShort();
 
3856
        sendString(buf);
 
3857
        numConsecutiveEmptyCells = 0;
 
3858
      }
 
3859
 
 
3860
      sendString("</TR>\n");
 
3861
    }
 
3862
 
 
3863
  sendString("</TABLE>"TABLE_OFF"\n<P>\n");
 
3864
  sendString("</CENTER>\n");
 
3865
 
 
3866
  printFooterHostLink();
 
3867
 
 
3868
  free(activeHosts);
 
3869
}
 
3870
 
 
3871
/* ************************ */
 
3872
 
 
3873
void printThptStatsMatrix(int sortedColumn) {
 
3874
  int i, dataSent;
 
3875
  char label[32], label1[32], buf[LEN_GENERAL_WORK_BUFFER], 
 
3876
    formatBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
 
3877
  time_t tmpTime;
 
3878
  struct tm t;
 
3879
  HostTraffic *el;
 
3880
 
 
3881
  printHTMLheader("Network Load Statistics Matrix", NULL, 0);
 
3882
 
 
3883
  switch(sortedColumn) {
 
3884
  case 1:
 
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");
 
3891
 
 
3892
    for(i=0; i<60; i++) {
 
3893
      if(myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].trafficValue == 0)
 
3894
        break;
 
3895
 
 
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&nbsp;-&nbsp;%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)
 
3908
        BufferTooShort();
 
3909
      sendString(buf);
 
3910
 
 
3911
      dataSent = 0;
 
3912
 
 
3913
      /* ************************* */
 
3914
 
 
3915
      if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].topHostSentSerial)) {
 
3916
        HostTraffic tmpEl;
 
3917
 
 
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)
 
3925
            BufferTooShort();
 
3926
          sendString(buf); dataSent = 1;
 
3927
        }
 
3928
      }
 
3929
 
 
3930
      if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].secondHostSentSerial)) {
 
3931
        HostTraffic tmpEl;
 
3932
 
 
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)
 
3940
            BufferTooShort();
 
3941
          sendString(buf); dataSent = 1;
 
3942
        }
 
3943
      }
 
3944
 
 
3945
      if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].thirdHostSentSerial)) {
 
3946
        HostTraffic tmpEl;
 
3947
 
 
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)
 
3955
            BufferTooShort();
 
3956
          sendString(buf); dataSent = 1;
 
3957
        }
 
3958
      }
 
3959
 
 
3960
      /* ************************* */
 
3961
 
 
3962
      if(!dataSent) sendString("&nbsp;");
 
3963
      sendString("</TABLE>"TABLE_OFF"</TD><TD "TD_BG" ALIGN=LEFT><TABLE BORDER=1 "TABLE_DEFAULTS" WIDTH=100%%>\n");
 
3964
      dataSent = 0;
 
3965
 
 
3966
      /* ************************* */
 
3967
 
 
3968
      if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].topHostRcvdSerial)) {
 
3969
        HostTraffic tmpEl;
 
3970
 
 
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)
 
3978
            BufferTooShort();
 
3979
          sendString(buf); dataSent = 1;
 
3980
        }
 
3981
      }
 
3982
 
 
3983
      if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].secondHostRcvdSerial)) {
 
3984
        HostTraffic tmpEl;
 
3985
 
 
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)
 
3993
            BufferTooShort();
 
3994
          sendString(buf); dataSent = 1;
 
3995
        }
 
3996
      }
 
3997
 
 
3998
      if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last60MinutesThpt[i].thirdHostRcvdSerial)) {
 
3999
        HostTraffic tmpEl;
 
4000
 
 
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)
 
4008
            BufferTooShort();
 
4009
          sendString(buf); dataSent = 1;
 
4010
        }
 
4011
      }
 
4012
 
 
4013
      /* ************************* */
 
4014
 
 
4015
      if(!dataSent) sendString("&nbsp;");
 
4016
      sendString("</TABLE></TD></TR>\n");
 
4017
    }
 
4018
    break;
 
4019
  case 2:
 
4020
  default:
 
4021
    if(myGlobals.device[myGlobals.actualReportDeviceId].numThptSamples < 60) {
 
4022
      printNoDataYet();
 
4023
      return;
 
4024
    } else {
 
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>"
 
4029
                 "</TR>\n");
 
4030
 
 
4031
      for(i=0; i<24; i++) {
 
4032
        if(myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].trafficValue == 0)
 
4033
          break;
 
4034
 
 
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&nbsp;-&nbsp;%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)
 
4045
          BufferTooShort();
 
4046
        sendString(buf);
 
4047
 
 
4048
        /* ************************* */
 
4049
 
 
4050
        if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].topHostSentSerial)) {
 
4051
          HostTraffic tmpEl;
 
4052
 
 
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)
 
4060
              BufferTooShort();
 
4061
            sendString(buf);
 
4062
          }
 
4063
        }
 
4064
 
 
4065
        if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].secondHostSentSerial)) {
 
4066
          HostTraffic tmpEl;
 
4067
 
 
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)
 
4075
              BufferTooShort();
 
4076
            sendString(buf);
 
4077
          }
 
4078
        }
 
4079
 
 
4080
        if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].thirdHostSentSerial)) {
 
4081
          HostTraffic tmpEl;
 
4082
 
 
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)
 
4090
              BufferTooShort();
 
4091
            sendString(buf);
 
4092
          }
 
4093
        }
 
4094
 
 
4095
        /* ************************* */
 
4096
 
 
4097
        sendString("&nbsp;");
 
4098
        sendString("</TABLE>"TABLE_OFF"</TD><TD "TD_BG" ALIGN=LEFT "DARK_BG">"TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS">\n");
 
4099
 
 
4100
        /* ************************* */
 
4101
 
 
4102
        if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].topHostRcvdSerial)) {
 
4103
          HostTraffic tmpEl;
 
4104
 
 
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)
 
4112
              BufferTooShort();
 
4113
            sendString(buf);
 
4114
          }
 
4115
        }
 
4116
 
 
4117
        if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].secondHostRcvdSerial)) {
 
4118
          HostTraffic tmpEl;
 
4119
 
 
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)
 
4127
              BufferTooShort();
 
4128
            sendString(buf);
 
4129
          }
 
4130
        }
 
4131
 
 
4132
        if(!emptySerial(&myGlobals.device[myGlobals.actualReportDeviceId].last24HoursThpt[i].thirdHostRcvdSerial)) {
 
4133
          HostTraffic tmpEl;
 
4134
 
 
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)
 
4142
              BufferTooShort();
 
4143
            sendString(buf);
 
4144
          }
 
4145
        }
 
4146
 
 
4147
        /* ************************* */
 
4148
 
 
4149
        sendString("&nbsp;");
 
4150
        sendString("</TABLE>"TABLE_OFF"</TD></TR>\n");
 
4151
      }
 
4152
    }
 
4153
    break;
 
4154
  }
 
4155
 
 
4156
  sendString("</TABLE>"TABLE_OFF"</CENTER>\n");
 
4157
}
 
4158
 
 
4159
/* ************************ */
 
4160
 
 
4161
void printThptStats(int sortedColumn _UNUSED_) {
 
4162
  char tmpBuf[128], formatBuf[32], formatBuf1[32];
 
4163
 
 
4164
  printHTMLheader("Network Load Statistics", NULL, 0);
 
4165
 
 
4166
  if(myGlobals.device[myGlobals.actualReportDeviceId].dummyDevice) {
 
4167
    printFlagedWarning("<I>Network load statistics are not available for virtual interfaces</I>");
 
4168
    return;
 
4169
  }
 
4170
 
 
4171
  if(myGlobals.device[myGlobals.actualReportDeviceId].numThptSamples == 0) {
 
4172
    printNoDataYet();
 
4173
    return;
 
4174
  }
 
4175
 
 
4176
  sendString("<CENTER>\n");
 
4177
 
 
4178
#ifndef EMBEDDED
 
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");
 
4181
#endif
 
4182
 
 
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();
 
4186
 
 
4187
  sendString(tmpBuf);
 
4188
 
 
4189
  if(myGlobals.device[myGlobals.actualReportDeviceId].numThptSamples > 60) {
 
4190
#ifndef EMBEDDED
 
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");
 
4193
#endif
 
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();
 
4197
 
 
4198
    sendString(tmpBuf);
 
4199
 
 
4200
#ifndef EMBEDDED
 
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)
 
4206
        BufferTooShort();
 
4207
      sendString(tmpBuf);
 
4208
    }
 
4209
#endif
 
4210
  }
 
4211
 
 
4212
  sendString("</CENTER>\n");
 
4213
}
 
4214
 
 
4215
/* ************************ */
 
4216
 
 
4217
static int cmpStatsFctn(const void *_a, const void *_b) {
 
4218
  DomainStats *a = (DomainStats *)_a;
 
4219
  DomainStats *b = (DomainStats *)_b;
 
4220
  Counter a_, b_;
 
4221
  int rc;
 
4222
 
 
4223
  if((a == NULL) && (b != NULL)) {
 
4224
    traceEvent(CONST_TRACE_WARNING, "cmpStatsFctn() (1)");
 
4225
    return(1);
 
4226
  } else if((a != NULL) && (b == NULL)) {
 
4227
    traceEvent(CONST_TRACE_WARNING, "cmpStatsFctn() (2)");
 
4228
    return(-1);
 
4229
  } else if((a == NULL) && (b == NULL)) {
 
4230
    traceEvent(CONST_TRACE_WARNING, "cmpStatsFctn() (3)");
 
4231
    return(0);
 
4232
  }
 
4233
 
 
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.
 
4238
     */
 
4239
    rc = cmpFctnLocationName(a, b);
 
4240
    return(rc);
 
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;
 
4251
  default:
 
4252
  case 0: /* Host */
 
4253
    rc = cmpFctnResolvedName(&(a->domainHost), &(b->domainHost));
 
4254
    return(rc);
 
4255
  }
 
4256
 
 
4257
  if(a_ < b_)
 
4258
    return(1);
 
4259
  else if (a_ > b_)
 
4260
    return(-1);
 
4261
  else
 
4262
    return(0);
 
4263
}
 
4264
 
 
4265
/* ****************************************** */
 
4266
 
 
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;
 
4271
  HostTraffic *el;
 
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];
 
4280
 
 
4281
  if(domainName == NULL) {
 
4282
    if(snprintf(buf, sizeof(buf), "Statistics for all Domains") < 0)
 
4283
      BufferTooShort();
 
4284
  } else {
 
4285
    if(snprintf(buf, sizeof(buf), "Statistics for hosts in Domain <i>%s</i>", domainName) < 0)
 
4286
      BufferTooShort();
 
4287
  }
 
4288
  printHTMLheader(buf, NULL, 0);
 
4289
 
 
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)
 
4294
      return;
 
4295
 
 
4296
  /* Fix below courtesy of Francis Pintos <francis@arhl.com.hk> */
 
4297
  len = sizeof(DomainStats**)*maxHosts;
 
4298
  stats = (DomainStats**)mallocAndInitWithReportWarn(len, "printDomainStats(2)");
 
4299
  if(stats == NULL)
 
4300
      return;
 
4301
 
 
4302
  /* traceEvent(CONST_TRACE_INFO, "'%s' '%d' '%d'", domainName, sortedColumn, revertOrder); */
 
4303
 
 
4304
  if(revertOrder) {
 
4305
    sign = "";
 
4306
    arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
4307
  } else {
 
4308
    sign = "-";
 
4309
    arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
4310
  }
 
4311
 
 
4312
  for(el=getFirstHost(myGlobals.actualReportDeviceId);
 
4313
      el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
 
4314
    fillDomainName(el);
 
4315
 
 
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)
 
4322
       ) {
 
4323
      continue;
 
4324
    } else if((domainName != NULL)
 
4325
              && (strcmp(el->dnsDomainValue, domainName) != 0)) {
 
4326
      continue;
 
4327
    }
 
4328
 
 
4329
    if(domainName == NULL) {
 
4330
      for(keyValue=0, tmpIdx=0; el->dnsDomainValue[tmpIdx] != '\0'; tmpIdx++)
 
4331
        keyValue += (tmpIdx+1)*(u_short)el->dnsDomainValue[tmpIdx];
 
4332
 
 
4333
      keyValue %= maxHosts;
 
4334
 
 
4335
      while((stats[keyValue] != NULL)
 
4336
            && (strcasecmp(stats[keyValue]->domainHost->dnsDomainValue, el->dnsDomainValue) != 0))
 
4337
        keyValue = (keyValue+1) % maxHosts;
 
4338
 
 
4339
      if(stats[keyValue] != NULL)
 
4340
        statsEntry = stats[keyValue];
 
4341
      else {
 
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); */
 
4347
      }
 
4348
    } else {
 
4349
      statsEntry = &tmpStats[numEntries++];
 
4350
      memset(statsEntry, 0, sizeof(DomainStats));
 
4351
      statsEntry->domainHost = el;
 
4352
      stats[keyValue++] = statsEntry;
 
4353
    }
 
4354
 
 
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;
 
4367
 
 
4368
    if(numEntries >= maxHosts) break;
 
4369
  } /* for(;;) */
 
4370
 
 
4371
  if(numEntries == 0) {
 
4372
    printNoDataYet();
 
4373
    free(tmpStats); free(stats);
 
4374
    return;
 
4375
  }
 
4376
 
 
4377
  myGlobals.columnSort = sortedColumn;
 
4378
 
 
4379
  qsort(tmpStats, numEntries, sizeof(DomainStats), cmpStatsFctn);
 
4380
 
 
4381
  /* avoid division by zero */
 
4382
  if(totBytesSent == 0)
 
4383
    totBytesSent = 1;
 
4384
  if(totBytesRcvd == 0)
 
4385
    totBytesRcvd = 1;
 
4386
 
 
4387
  if(domainName == NULL) {
 
4388
    if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", CONST_DOMAIN_STATS_HTML, sign) < 0)
 
4389
      BufferTooShort();
 
4390
    if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", CONST_DOMAIN_STATS_HTML) < 0)
 
4391
      BufferTooShort();
 
4392
  } else {
 
4393
    if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?dom=%s&col=%s",
 
4394
                CONST_DOMAIN_STATS_HTML, domainName, sign) < 0)
 
4395
      BufferTooShort();
 
4396
    if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?dom=%s&col=",
 
4397
                CONST_DOMAIN_STATS_HTML, domainName) < 0)
 
4398
      BufferTooShort();
 
4399
  }
 
4400
   
 
4401
  for(i=0; i<=15; i++)
 
4402
    if(abs(myGlobals.columnSort) == i)
 
4403
      arrow[i] = arrowGif, theAnchor[i] = htmlAnchor;
 
4404
    else
 
4405
      arrow[i] = "", theAnchor[i] = htmlAnchor1;
 
4406
  
 
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)
 
4417
    BufferTooShort();
 
4418
  sendString(buf);
 
4419
 
 
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");
 
4425
 
 
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)
 
4448
    BufferTooShort();
 
4449
  sendString(buf);
 
4450
 
 
4451
  for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
4452
    if(revertOrder)
 
4453
      statsEntry = &tmpStats[numEntries-idx-1];
 
4454
    else
 
4455
      statsEntry = &tmpStats[idx];
 
4456
 
 
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)
 
4461
        BufferTooShort();
 
4462
    } else {
 
4463
      char tmpBuf[64], *hostLink;
 
4464
      int blankId;
 
4465
 
 
4466
      accessAddrResMutex("getHostIcon");
 
4467
 
 
4468
      blankId = strlen(statsEntry->domainHost->hostResolvedName)-
 
4469
        strlen(statsEntry->domainHost->dnsDomainValue)-1;
 
4470
 
 
4471
      strncpy(tmpBuf, statsEntry->domainHost->hostResolvedName, sizeof(tmpBuf));
 
4472
 
 
4473
      releaseAddrResMutex();
 
4474
 
 
4475
      if((blankId > 0)
 
4476
         && (strcmp(&tmpBuf[blankId+1], domainName) == 0))
 
4477
        tmpBuf[blankId] = '\0';
 
4478
 
 
4479
      hostLink = makeHostLink(statsEntry->domainHost, FLAG_HOSTLINK_TEXT_FORMAT, 1,
 
4480
                              0, hostLinkBuf, sizeof(hostLinkBuf));
 
4481
 
 
4482
      len = strlen(hostLink); if(len >= sizeof(htmlAnchor)) len = sizeof(htmlAnchor)-1;
 
4483
      strncpy(htmlAnchor, hostLink, len);
 
4484
      htmlAnchor[len] = '\0';
 
4485
    }
 
4486
 
 
4487
 
 
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();
 
4508
    sendString(buf);
 
4509
 
 
4510
    /* Avoid huge tables */
 
4511
    if(printedEntries++ > myGlobals.maxNumLines)
 
4512
      break;
 
4513
  }
 
4514
 
 
4515
  sendString("</TABLE>"TABLE_OFF"</HTML>\n");
 
4516
  sendString("</CENTER>\n");
 
4517
 
 
4518
  if(domainName != NULL) {
 
4519
    if(snprintf(buf, sizeof(buf), "%s?dom=%s", CONST_DOMAIN_STATS_HTML, domainName) < 0)
 
4520
      BufferTooShort();
 
4521
  } else {
 
4522
    if(snprintf(buf, sizeof(buf), "%s", CONST_DOMAIN_STATS_HTML) < 0)
 
4523
      BufferTooShort();
 
4524
  }
 
4525
 
 
4526
  addPageIndicator(buf, pageNum, numEntries,
 
4527
                   myGlobals.maxNumLines,
 
4528
                   revertOrder, abs(sortedColumn));
 
4529
 
 
4530
#ifndef EMBEDDED
 
4531
  /* RRDs for domains */
 
4532
  if (domainName != NULL) {
 
4533
    struct stat statbufDomain;
 
4534
 
 
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)
 
4539
      BufferTooShort();
 
4540
  
 
4541
    if((i = stat(buf, &statbufDomain)) == 0) {
 
4542
      if(snprintf(buf, sizeof(buf), 
 
4543
                  "<p>&nbsp;</p>\n"
 
4544
                  "<center><table border=\"0\"><tr>"
 
4545
                  "<td valign=\"middle\" align=\"right\">Show domain-wide traffic charts:</td>\n"
 
4546
                  "<td align=\"right\">"
 
4547
                  "&nbsp;&nbsp;"
 
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> ]"
 
4551
                  "&nbsp;&nbsp;"
 
4552
                  "</td>\n"
 
4553
                  "</tr></table>\n</center>\n"
 
4554
                  "<p>&nbsp;</p>\n",
 
4555
                myGlobals.device[myGlobals.actualReportDeviceId].humanFriendlyName,
 
4556
                domainName,domainName) < 0)
 
4557
        BufferTooShort();
 
4558
      sendString(buf);
 
4559
    }
 
4560
  }
 
4561
#endif
 
4562
 
 
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");
 
4566
 
 
4567
  free(tmpStats); free(stats);
 
4568
}
 
4569
 
 
4570
/* ************************* */
 
4571
 
 
4572
void printNoDataYet(void) {
 
4573
  printFlagedWarning("<I>No Data To Display (yet)</I>");
 
4574
}
 
4575
 
 
4576
/* ************************* */
 
4577
 
 
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>",
 
4582
              flagName) < 0)
 
4583
    BufferTooShort();
 
4584
  printFlagedWarning(buf);
 
4585
}
 
4586
 
 
4587
/* ************************* */
 
4588
 
 
4589
void listNetFlows(void) {
 
4590
  char buf[LEN_GENERAL_WORK_BUFFER];
 
4591
  int numEntries=0;
 
4592
  FlowFilterList *list = myGlobals.flowsList;
 
4593
  char formatBuf[32], formatBuf1[32];
 
4594
 
 
4595
  printHTMLheader(NULL, NULL, 0);
 
4596
 
 
4597
  if(list != NULL) {
 
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>");
 
4605
        }
 
4606
 
 
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();
 
4612
        sendString(buf);
 
4613
 
 
4614
        numEntries++;
 
4615
      }
 
4616
 
 
4617
      list = list->next;
 
4618
    }
 
4619
 
 
4620
    if(numEntries > 0)
 
4621
      sendString("</TABLE>"TABLE_OFF"\n");
 
4622
 
 
4623
    sendString("</CENTER>\n");
 
4624
  }
 
4625
 
 
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");
 
4629
  }
 
4630
}
 
4631
 
 
4632
/* *********************************** */
 
4633
 
 
4634
void printHostHourlyTraffic(HostTraffic *el) {
 
4635
  Counter tcSent, tcRcvd;
 
4636
  int i, hourId, j;
 
4637
  char theDate[8], macAddr[24];
 
4638
  struct tm t;
 
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"};
 
4644
 
 
4645
  if(el->trafficDistribution == NULL) return;
 
4646
 
 
4647
  strftime(theDate, 8, CONST_TOD_HOUR_TIMESPEC, localtime_r(&myGlobals.actTime, &t));
 
4648
  hourId = atoi(theDate);
 
4649
 
 
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
 
4652
   * FC_Ports
 
4653
   */
 
4654
  if (isFcHost (el)) {
 
4655
      printSectionTitle("FibreChannel Port Traffic Stats");
 
4656
  }
 
4657
  else {
 
4658
      printSectionTitle("Host Traffic Stats");
 
4659
  }
 
4660
  
 
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>");
 
4668
 
 
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;
 
4672
  }
 
4673
 
 
4674
  for (i = 0, j = hourId; i < 24; i++) {
 
4675
    j = j%24;
 
4676
    if (snprintf (buf, sizeof (buf), "<TR><TH "TH_BG" ALIGN=RIGHT "DARK_BG">%s</TH>\n", hours[j]) < 0)
 
4677
      BufferTooShort();
 
4678
    sendString(buf);
 
4679
    printHostHourlyTrafficEntry(el, j, tcSent, tcRcvd);
 
4680
    if(!j)
 
4681
      j = 23;
 
4682
    else
 
4683
      j--;
 
4684
  }
 
4685
  
 
4686
  sendString("<TR><TH "TH_BG" "DARK_BG">Total</TH>\n");
 
4687
 
 
4688
  if (isFcHost (el)) {
 
4689
      targetStr = el->hostNumFcAddress;
 
4690
  }
 
4691
  else {
 
4692
      if(snprintf(macAddr, sizeof(macAddr), "%s", el->ethAddressString) < 0)
 
4693
        BufferTooShort();
 
4694
      targetStr = el->hostNumIpAddress[0] == '\0' ?  macAddr : el->hostNumIpAddress;
 
4695
  }
 
4696
 
 
4697
  urlFixupToRFC1945Inplace(targetStr);
 
4698
  
 
4699
  if(tcSent > 0) {
 
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\">"
 
4703
                                  "</TD>\n",
 
4704
                targetStr) < 0)
 
4705
      BufferTooShort();
 
4706
    sendString(buf);   
 
4707
  } else
 
4708
       sendString("<TD COLSPAN=2 "TD_BG">&nbsp;</TD>\n");
 
4709
 
 
4710
  if(tcRcvd > 0) {
 
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\">"
 
4714
                                  "</TD>\n",
 
4715
                targetStr) < 0)
 
4716
      BufferTooShort();
 
4717
    sendString(buf);   
 
4718
  } else
 
4719
    sendString("<TD COLSPAN=2 "TD_BG">&nbsp;</TD>\n");
 
4720
 
 
4721
  sendString("</TR>\n");
 
4722
 
 
4723
  sendString("</TABLE>"TABLE_OFF"\n</CENTER>\n");
 
4724
}
 
4725
 
 
4726
/* ************************** */
 
4727
 
 
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];
 
4734
 
 
4735
  maxHosts = ifName->hostsno; /* save it as it can change */
 
4736
 
 
4737
  tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(maxHosts*sizeof(HostTraffic*), "dumpHostsCriteria");
 
4738
  if(tmpTable == NULL)
 
4739
    return;
 
4740
 
 
4741
  switch(criteria) {
 
4742
  case 0: /* AS */
 
4743
    myGlobals.columnSort = 10;
 
4744
    break;
 
4745
  case 1: /* VLAN */
 
4746
    myGlobals.columnSort = 11;
 
4747
    break;
 
4748
  }
 
4749
 
 
4750
  for(el=getFirstHost(myGlobals.actualReportDeviceId);
 
4751
      el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
 
4752
    switch(criteria) {
 
4753
    case 0: /* AS */
 
4754
      getHostAS(el);
 
4755
      if(el->hostAS > 0)  tmpTable[numEntries++] = el;
 
4756
      break;
 
4757
    case 1: /* VLAN */
 
4758
      if(el->vlanId > 0)  tmpTable[numEntries++] = el;
 
4759
      break;
 
4760
    }
 
4761
 
 
4762
    if(numEntries >= maxHosts)
 
4763
      break;
 
4764
  }
 
4765
 
 
4766
  if(numEntries > 0) {
 
4767
    int lastId = 0;
 
4768
    Counter dataSent, dataRcvd;
 
4769
 
 
4770
    qsort(tmpTable, numEntries, sizeof(HostTraffic*), sortHostFctn);
 
4771
 
 
4772
    /*
 
4773
      AS Data Sent/Rcvd patch courtesy of Marco Sanson <marco.sanson@infvic.it>
 
4774
    */
 
4775
 
 
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)
 
4783
      BufferTooShort();
 
4784
    sendString(buf);
 
4785
 
 
4786
    dataSent = dataRcvd = 0;
 
4787
 
 
4788
    for(i=0; i<numEntries; i++) {
 
4789
      el = tmpTable[numEntries-i-1];
 
4790
 
 
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>");
 
4795
      } else {
 
4796
        /* New AS or VLAN */
 
4797
 
 
4798
        if(i>0) {
 
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"
 
4803
                      "</TR>\n",
 
4804
                      formatBytes(dataSent, 1, formatBuf, sizeof(formatBuf)),
 
4805
                      formatBytes(dataRcvd, 1, formatBuf1, sizeof(formatBuf1))) < 0)
 
4806
            BufferTooShort();
 
4807
          sendString(buf);
 
4808
        }
 
4809
 
 
4810
        /* Start new row */
 
4811
        dataSent = dataRcvd = 0;
 
4812
 
 
4813
        sendString("<TR "TR_ON">\n");
 
4814
 
 
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>"
 
4820
                      "</TH>\n",
 
4821
                      el->hostAS, el->hostAS) < 0)
 
4822
            BufferTooShort();
 
4823
        } else {
 
4824
          lastId = el->vlanId;
 
4825
          if(snprintf(buf, sizeof(buf),
 
4826
                      "<TH "TH_BG" ALIGN=RIGHT>%d</TH>\n",
 
4827
                      el->vlanId) < 0)
 
4828
            BufferTooShort();
 
4829
        }
 
4830
        sendString(buf);
 
4831
 
 
4832
        sendString("<TH "TH_BG" ALIGN=LEFT>");
 
4833
 
 
4834
      }
 
4835
 
 
4836
      sendString(makeHostLink(el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, 
 
4837
                              hostLinkBuf, sizeof(hostLinkBuf)));
 
4838
 
 
4839
      dataSent += el->bytesSent.value;
 
4840
      dataRcvd += el->bytesRcvd.value;
 
4841
    }
 
4842
        
 
4843
    if(i>0) {
 
4844
      sendString("</TH>\n");
 
4845
 
 
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)
 
4850
        BufferTooShort();
 
4851
      sendString(buf);
 
4852
    }
 
4853
 
 
4854
    sendString("</TR>\n</TABLE>\n</CENTER>");
 
4855
 
 
4856
  } else {
 
4857
    printFlagedWarning("<I>No entries to display(yet)</I>");
 
4858
  }
 
4859
 
 
4860
  free(tmpTable);
 
4861
}
 
4862
 
 
4863
/* ************************** */
 
4864
 
 
4865
void printASList(unsigned int deviceId) {
 
4866
  printHTMLheader("Autonomous Systems Traffic Statistics", NULL, 0);
 
4867
 
 
4868
  if(deviceId > myGlobals.numDevices) {
 
4869
    printFlagedWarning("<I>Invalid device specified</I>");
 
4870
    return;
 
4871
  }
 
4872
 
 
4873
  dumpHostsCriteria(&myGlobals.device[deviceId], 0 /* AS */);
 
4874
}
 
4875
 
 
4876
/* ******************************* */
 
4877
 
 
4878
void printVLANList(unsigned int deviceId) {
 
4879
  printHTMLheader("VLAN Traffic Statistics", NULL, 0);
 
4880
 
 
4881
  if(deviceId > myGlobals.numDevices) {
 
4882
    printFlagedWarning("<I>Invalid device specified</I>");
 
4883
    return;
 
4884
  }
 
4885
 
 
4886
  dumpHostsCriteria(&myGlobals.device[deviceId], 1 /* VLAN */);
 
4887
}
 
4888
 
 
4889
/* ******************************************* */
 
4890
 
 
4891
static int recentlyUsedPort(HostTraffic *el, int portNr, int serverPort) {
 
4892
  int i;
 
4893
 
 
4894
  if(el == NULL) return(0);
 
4895
 
 
4896
  for(i=0; i<MAX_NUM_RECENT_PORTS; i++) {
 
4897
    if(serverPort) {
 
4898
      if(el->recentlyUsedServerPorts[i] == portNr)
 
4899
        return(1);
 
4900
    } else {
 
4901
      if(el->recentlyUsedClientPorts[i] == portNr)
 
4902
        return(1);
 
4903
    }
 
4904
  }
 
4905
 
 
4906
  return(0);
 
4907
}
 
4908
 
 
4909
/* ******************************************* */
 
4910
 
 
4911
void showPortTraffic(u_short portNr) {
 
4912
  char buf[LEN_GENERAL_WORK_BUFFER], *str;
 
4913
  int numRecords = 0, firstRun = 1;
 
4914
  HostTraffic *el;
 
4915
  char portBuf[32], hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
 
4916
 
 
4917
  str = getAllPortByNum(portNr, portBuf, sizeof(portBuf));
 
4918
 
 
4919
  if((str[0] == '?') || (atoi(str) == portNr)) {
 
4920
    if(snprintf(buf, sizeof(buf), "Recent Users of Port %u", portNr) < 0)
 
4921
      BufferTooShort();
 
4922
  } else {
 
4923
    if(snprintf(buf, sizeof(buf), "Recent Users of Port %u (%s)", portNr, str) < 0)
 
4924
      BufferTooShort();
 
4925
  }
 
4926
 
 
4927
  printHTMLheader(buf, NULL, 0);
 
4928
  sendString("<CENTER>\n");
 
4929
 
 
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");
 
4937
      }
 
4938
 
 
4939
      sendString("\n<LI> ");
 
4940
      sendString(makeHostLink(el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)));
 
4941
      numRecords++;
 
4942
    }
 
4943
 
 
4944
    if(el == myGlobals.broadcastEntry) break;
 
4945
  }
 
4946
 
 
4947
  if(firstRun) {
 
4948
    firstRun=0;
 
4949
    el = myGlobals.broadcastEntry;
 
4950
    goto recentlyUsedPortSent;
 
4951
  }
 
4952
 
 
4953
  firstRun = 1;
 
4954
 
 
4955
  if(numRecords > 0) {
 
4956
    sendString("\n&nbsp;\n</TD><TD>\n");
 
4957
  }
 
4958
 
 
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&nbsp;\n</TD><TD>\n");
 
4967
      }
 
4968
 
 
4969
      sendString("\n<LI> ");
 
4970
      sendString(makeHostLink(el, FLAG_HOSTLINK_TEXT_FORMAT, 0, 0, hostLinkBuf, sizeof(hostLinkBuf)));
 
4971
      numRecords++;
 
4972
    }
 
4973
 
 
4974
    if(el == myGlobals.broadcastEntry) break;
 
4975
  }
 
4976
 
 
4977
 
 
4978
  if(firstRun) {
 
4979
    firstRun = 0;
 
4980
    el = myGlobals.broadcastEntry;
 
4981
    goto recentlyUsedPortRcvd;
 
4982
  }
 
4983
 
 
4984
  if(numRecords == 0) {
 
4985
    sendString("<P>No hosts found: the information for this port has been purged in the meantime</CENTER><P>\n");
 
4986
  } else
 
4987
    sendString("\n&nbsp;\n</TD>\n</TR>\n</TABLE>\n</CENTER>");
 
4988
 
 
4989
}
 
4990
 
 
4991
/* ******************************************* */
 
4992
 
 
4993
void printFcHostsTraffic(int reportType,
 
4994
                         int sortedColumn,
 
4995
                         int revertOrder,
 
4996
                         int pageNum,
 
4997
                         char* url,
 
4998
                         LocalityDisplayPolicy showLocalityMode) {
 
4999
  u_int idx, numEntries=0, maxHosts, whatToDo;
 
5000
  int printedEntries=0, hourId;
 
5001
  char theDate[8];
 
5002
  struct tm t;
 
5003
  HostTraffic *el;
 
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;
 
5010
 
 
5011
    memset(buf, 0, sizeof(buf));
 
5012
    switch(reportType) {
 
5013
      case SORT_FC_ACTIVITY:
 
5014
        if(snprintf(buf, sizeof(buf), "FibreChannel Activity") < 0)
 
5015
          BufferTooShort();
 
5016
        break;
 
5017
      case SORT_FC_DATA:
 
5018
        if(snprintf(buf, sizeof(buf), "FibreChannel Traffic: ") < 0)
 
5019
          BufferTooShort();
 
5020
        break;
 
5021
      case SORT_FC_THPT:
 
5022
        if(snprintf(buf, sizeof(buf), "FibreChannel Throughput: ") < 0)
 
5023
          BufferTooShort();
 
5024
        break;
 
5025
      default:
 
5026
        if(snprintf(buf, sizeof(buf), "?? %d : ", reportType) < 0)
 
5027
          BufferTooShort();
 
5028
        break;
 
5029
    }
 
5030
 
 
5031
    if(reportType != SORT_FC_ACTIVITY) {
 
5032
      switch(showLocalityMode) {
 
5033
        case showSentReceived:
 
5034
          strncat(buf, "Data Sent+Received", sizeof(buf) - strlen(buf) - 1);
 
5035
          break;
 
5036
        case showOnlySent:
 
5037
          strncat(buf, "Data Sent", sizeof(buf) - strlen(buf) - 1);
 
5038
          break;
 
5039
        case showOnlyReceived:
 
5040
          strncat(buf, "Data Received", sizeof(buf) - strlen(buf) - 1);
 
5041
          break;
 
5042
      }
 
5043
    }
 
5044
    printHTMLheader(buf, 0, 0);
 
5045
 
 
5046
    maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
 
5047
 
 
5048
    tmpTable =  (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcHostsTraffic");
 
5049
    if(tmpTable == NULL)
 
5050
      return;
 
5051
 
 
5052
    strftime(theDate, 8, CONST_TOD_HOUR_TIMESPEC, localtime_r(&myGlobals.actTime, &t));
 
5053
    hourId = atoi(theDate);
 
5054
 
 
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;
 
5060
          
 
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;
 
5066
 
 
5067
              if (numEntries >= maxHosts)
 
5068
                  break;
 
5069
          }
 
5070
      }
 
5071
    }
 
5072
 
 
5073
    if(numEntries <= 0) {
 
5074
        printNoDataYet();
 
5075
        free(tmpTable);
 
5076
        return;
 
5077
    }
 
5078
 
 
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>]&nbsp;"
 
5084
             "[ <a href=\"%s?col=%s%d&showL=1\">Sent Only</a> ]&nbsp;"
 
5085
             "[ <a href=\"%s?col=%s%d&showL=2\">Received Only</a> ]&nbsp;</p>",
 
5086
             url, revertOrder ? "-" : "", sortedColumn, showLocalityMode,
 
5087
             url, revertOrder ? "-" : "", sortedColumn, showLocalityMode) < 0)
 
5088
            BufferTooShort();
 
5089
          break;
 
5090
        case showOnlySent:
 
5091
          if(snprintf(buf, sizeof(buf), "<p align=\"right\">"
 
5092
             "[ <a href=\"%s?col=%s%d&showH=%d&showL=0\">All</a> ]&nbsp;"
 
5093
             "[<b> Sent Only </b>]&nbsp;"
 
5094
             "[ <a href=\"%s?col=%s%d&showH=%d&showL=2\">Received Only</a> ]&nbsp;</p>",
 
5095
             url, revertOrder ? "-" : "", sortedColumn, showLocalityMode,
 
5096
             url, revertOrder ? "-" : "", sortedColumn, showLocalityMode) < 0)
 
5097
            BufferTooShort();
 
5098
          break;
 
5099
        default:
 
5100
          if(snprintf(buf, sizeof(buf), "<p align=\"right\">"
 
5101
             "[ <a href=\"%s?col=%s%d&showH=%d&showL=0\">All</a> ]&nbsp;"
 
5102
             "[ <a href=\"%s?col=%s%d&showH=%d&showL=1\">Sent Only</a> ]&nbsp;"
 
5103
             "[<b> Received Only </b>]&nbsp;</p>",
 
5104
             url, revertOrder ? "-" : "", sortedColumn, showLocalityMode,
 
5105
             url, revertOrder ? "-" : "", sortedColumn, showLocalityMode) < 0)
 
5106
            BufferTooShort();
 
5107
          break;
 
5108
      }
 
5109
      sendString(buf);
 
5110
    }
 
5111
 
 
5112
    printFcHeader(reportType, revertOrder, abs(sortedColumn), hourId, url);
 
5113
 
 
5114
    myGlobals.columnSort = sortedColumn;
 
5115
 
 
5116
#ifdef FC_DEBUG
 
5117
    traceEvent(CONST_TRACE_INFO, "FC_DEBUG: reportType=%d/sortedColumn=%d/myGlobals.columnSort=%d",
 
5118
               reportType, sortedColumn, myGlobals.columnSort);
 
5119
#endif
 
5120
 
 
5121
    myGlobals.reportKind = reportType;
 
5122
    /* if(myGlobals.columnSort == 0) myGlobals.reportKind = 0;*/
 
5123
 
 
5124
    qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpFcFctn);
 
5125
 
 
5126
    totFcBytesSent = totFcBytesRcvd = totFcBytes = 0;
 
5127
 
 
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;
 
5137
                break;
 
5138
              case showOnlySent:
 
5139
                totFcBytes += tmpTable[idx]->fcBytesSent.value;
 
5140
                break;
 
5141
              case showOnlyReceived:
 
5142
                totFcBytes += tmpTable[idx]->fcBytesRcvd.value;
 
5143
                break;
 
5144
            }
 
5145
        }
 
5146
    }
 
5147
 
 
5148
    /* Avoid core dumps */
 
5149
    if(totFcBytesSent == 0) totFcBytesSent = 1;
 
5150
    if(totFcBytesRcvd == 0) totFcBytesRcvd = 1;
 
5151
    if(totFcBytes == 0)     totFcBytes = 1;
 
5152
 
 
5153
#ifdef FC_DEBUG
 
5154
    traceEvent(CONST_TRACE_INFO, "FC_DEBUG: totIpBytesSent=%u, totIpBytesRcvd=%u totIpBytes=%u",
 
5155
               totFcBytesSent, totFcBytesRcvd, totFcBytes);
 
5156
#endif
 
5157
 
 
5158
    for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
5159
      char webHostName[LEN_GENERAL_WORK_BUFFER];
 
5160
 
 
5161
      if(revertOrder)
 
5162
        el = tmpTable[numEntries-idx-1];
 
5163
      else
 
5164
        el = tmpTable[idx];
 
5165
 
 
5166
      if(el != NULL) {
 
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;
 
5170
 
 
5171
        strncpy(webHostName,
 
5172
                makeFcHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0,
 
5173
                               hostLinkBuf, sizeof (hostLinkBuf)),
 
5174
                sizeof(webHostName));
 
5175
 
 
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...
 
5179
         */
 
5180
        whatToDo = 100*showLocalityMode + reportType;
 
5181
 
 
5182
        switch(whatToDo) {
 
5183
          case (100*showSentReceived + SORT_FC_DATA):
 
5184
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
 
5185
                      "%s%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>",
 
5190
                      getRowColor(),
 
5191
                      makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
 
5192
                                    vsanBuf, sizeof (vsanBuf)),
 
5193
                      webHostName,
 
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)
 
5202
              BufferTooShort();
 
5203
            break;
 
5204
          case (100*showOnlySent + SORT_FC_DATA):
 
5205
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
 
5206
                      "%s%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>",
 
5211
                      getRowColor(),
 
5212
                      makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
 
5213
                                    vsanBuf, sizeof (vsanBuf)),
 
5214
                      webHostName,
 
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)
 
5223
              BufferTooShort();
 
5224
            break;
 
5225
          case (100*showOnlyReceived + SORT_FC_DATA):
 
5226
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
 
5227
                      "%s%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>",
 
5232
                      getRowColor(),
 
5233
                      makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT, vsanBuf,
 
5234
                                    sizeof (vsanBuf)),
 
5235
                      webHostName,
 
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)
 
5244
              BufferTooShort();
 
5245
            break;
 
5246
          case (100*showSentReceived + SORT_FC_THPT):
 
5247
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
 
5248
                        "%s%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&nbsp;Pkts/sec</TD>"
 
5253
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>"
 
5254
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>",
 
5255
                        getRowColor(),
 
5256
                        makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
 
5257
                                      vsanBuf, sizeof (vsanBuf)),
 
5258
                        webHostName,
 
5259
                        formatThroughput(el->actualTThpt, 1, formatBuf[0], 32),
 
5260
                        formatThroughput(el->averageTThpt, 1, formatBuf[1], 32),
 
5261
                        formatThroughput(el->peakTThpt, 1, formatBuf[2], 32),
 
5262
                        el->actualTPktThpt,
 
5263
                        el->averageTPktThpt,
 
5264
                        el->peakTPktThpt) < 0)
 
5265
              BufferTooShort();
 
5266
            break;
 
5267
          case (100*showOnlySent + SORT_FC_THPT):
 
5268
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
 
5269
                        "%s%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&nbsp;Pkts/sec</TD>"
 
5274
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>"
 
5275
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>",
 
5276
                        getRowColor(),
 
5277
                        makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
 
5278
                                      vsanBuf, sizeof (vsanBuf)),
 
5279
                        webHostName,
 
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)
 
5286
              BufferTooShort();
 
5287
            break;
 
5288
          case (100*showOnlyReceived + SORT_FC_THPT):
 
5289
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
 
5290
                        "%s%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&nbsp;Pkts/sec</TD>"
 
5295
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>"
 
5296
                        "<TD "TD_BG" ALIGN=RIGHT>%.1f&nbsp;Pkts/sec</TD>",
 
5297
                        getRowColor(),
 
5298
                        makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
 
5299
                                      vsanBuf, sizeof (vsanBuf)),
 
5300
                        webHostName,
 
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)
 
5307
              BufferTooShort();
 
5308
            break;
 
5309
          case SORT_FC_ACTIVITY:
 
5310
            if(snprintf(buf, sizeof(buf), "<TR  "TR_ON" %s>"
 
5311
                        "%s%s",
 
5312
                        getRowColor(),
 
5313
                        makeVsanLink (el->vsanId, FLAG_HOSTLINK_HTML_FORMAT,
 
5314
                                      vsanBuf, sizeof (vsanBuf)),
 
5315
                        webHostName) < 0)
 
5316
              BufferTooShort();
 
5317
            sendString(buf);
 
5318
            printHostThtpShort(el, reportType, hourId);
 
5319
            buf[0]='\0';
 
5320
            break;
 
5321
        }
 
5322
        sendString(buf);
 
5323
        sendString("</TR>\n");
 
5324
 
 
5325
        /* Avoid huge tables */
 
5326
        if(printedEntries++ > myGlobals.maxNumLines)
 
5327
          break;
 
5328
      }
 
5329
    }
 
5330
 
 
5331
    sendString("\n</TABLE>"TABLE_OFF"\n");
 
5332
 
 
5333
    switch(reportType) {
 
5334
      case SORT_FC_THPT:
 
5335
        break;
 
5336
      case SORT_FC_ACTIVITY:
 
5337
        break;
 
5338
      case SORT_FC_DATA:
 
5339
        sendString("<P><I>Note: These counters do not include broadcasts and "
 
5340
                   "will not equal the 'Global Protocol Distribution'</I></P>\n");
 
5341
        break;
 
5342
    }
 
5343
 
 
5344
    sendString("</CENTER>\n");
 
5345
 
 
5346
    printFooter(reportType);
 
5347
 
 
5348
    addPageIndicator(url, pageNum, numEntries, myGlobals.maxNumLines,
 
5349
                     revertOrder, abs(sortedColumn));
 
5350
 
 
5351
    myGlobals.lastRefreshTime = myGlobals.actTime;
 
5352
    free(tmpTable);
 
5353
}
 
5354
 
 
5355
/* ******************************* */
 
5356
 
 
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];
 
5366
 
 
5367
    printHTMLheader("FibreChannel Hosts Information", 0, 0);
 
5368
 
 
5369
    maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
 
5370
 
 
5371
    tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcHostsInfo");
 
5372
    if(tmpTable == NULL)
 
5373
      return;
 
5374
 
 
5375
    memset(buf, 0, sizeof(buf));
 
5376
 
 
5377
    if(revertOrder) {
 
5378
        sign = "";
 
5379
        arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
5380
    } else {
 
5381
        sign = "-";
 
5382
        arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
5383
    }
 
5384
 
 
5385
    myGlobals.columnSort = sortedColumn;
 
5386
 
 
5387
    numEntries = 0;
 
5388
 
 
5389
    for(el=getFirstHost(myGlobals.actualReportDeviceId);
 
5390
        el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
 
5391
        unsigned short actUsage;
 
5392
 
 
5393
        if (!isFcHost (el) || (el->vsanId > MAX_USER_VSAN)) continue;
 
5394
            
 
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;
 
5402
            
 
5403
            tmpTable[numEntries++]=el;
 
5404
            
 
5405
            if(numEntries >= maxHosts)
 
5406
                break;
 
5407
        }
 
5408
    }
 
5409
 
 
5410
    if(numEntries <= 0) {
 
5411
        printNoDataYet();
 
5412
        free(tmpTable);
 
5413
        return;
 
5414
    }
 
5415
 
 
5416
    qsort(tmpTable, numEntries, sizeof(struct hostTraffic*), sortHostFctn);
 
5417
 
 
5418
    if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s",
 
5419
                CONST_FC_HOSTS_INFO_HTML, sign) < 0)
 
5420
        BufferTooShort();
 
5421
    if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=",
 
5422
                CONST_FC_HOSTS_INFO_HTML) < 0)
 
5423
        BufferTooShort();
 
5424
 
 
5425
    for(i=1; i<=9; i++) {
 
5426
        if(abs(myGlobals.columnSort) == i) {
 
5427
            arrow[i] = arrowGif;
 
5428
            theAnchor[i] = htmlAnchor;
 
5429
        } else {
 
5430
            arrow[i] = "";
 
5431
            theAnchor[i] = htmlAnchor1;
 
5432
        }
 
5433
    }
 
5434
 
 
5435
    if(abs(myGlobals.columnSort) == FLAG_DOMAIN_DUMMY_IDX) {
 
5436
        arrow[0] = arrowGif;
 
5437
        theAnchor[0] = htmlAnchor;
 
5438
    } else {
 
5439
        arrow[0] = "";
 
5440
        theAnchor[0] = htmlAnchor1;
 
5441
    }
 
5442
 
 
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&nbsp;Address%s</A></TH>\n"
 
5447
                 "<TH "TH_BG" "DARK_BG">%s4>Sent&nbsp;Bandwidth%s</A></TH>"
 
5448
                 "<TH "TH_BG" "DARK_BG">Nw&nbsp;Board&nbsp;Vendor</TH>"
 
5449
                 "<TH "TH_BG" "DARK_BG">%s9>Age%s</A></TH>"
 
5450
                 "</TR>\n",
 
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]
 
5456
            ) < 0)
 
5457
        BufferTooShort();
 
5458
 
 
5459
    sendString(buf);
 
5460
 
 
5461
    for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
5462
        if(revertOrder)
 
5463
            el = tmpTable[numEntries-idx-1];
 
5464
        else
 
5465
            el = tmpTable[idx];
 
5466
 
 
5467
        if(el != NULL) {
 
5468
            char *tmpName1, *tmpName2;
 
5469
 
 
5470
            strncpy (tmpbuf, fc_to_str ((u_int8_t *)&el->hostFcAddress),
 
5471
                     LEN_FC_ADDRESS_DISPLAY);
 
5472
            tmpName1 = tmpbuf;
 
5473
 
 
5474
            if((tmpName1[0] == '\0') || (strcmp(tmpName1, "0.0.0.0") == 0))
 
5475
                tmpName1 = myGlobals.separator;
 
5476
 
 
5477
            tmpName2 = getVendorInfo (&el->pWWN.str[2], 0);
 
5478
            if (tmpName2[0] == '\0') {
 
5479
                tmpName2 = "N/A";
 
5480
            }
 
5481
#ifdef FC_DEBUG
 
5482
            traceEvent(CONST_TRACE_INFO, "FC_DEBUG: %s <=> %s [%s/%s]",
 
5483
                       el->hostNumIpAddress, sniffedName,
 
5484
                       el->hostResolvedName, el->hostNumIpAddress);
 
5485
#endif
 
5486
    
 
5487
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>", getRowColor()) < 0)
 
5488
                BufferTooShort();
 
5489
            sendString(buf);
 
5490
 
 
5491
            if (snprintf (buf, sizeof (buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
 
5492
                          makeVsanLink (el->vsanId, 0,
 
5493
                                        vsanBuf, sizeof (vsanBuf))) < 0)
 
5494
            BufferTooShort();
 
5495
            sendString (buf);
 
5496
            
 
5497
            sendString(makeFcHostLink(el, FLAG_HOSTLINK_HTML_FORMAT, 0, 0,
 
5498
                                      hostLinkBuf, sizeof (hostLinkBuf)));
 
5499
    
 
5500
            if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>",
 
5501
                        tmpName1) < 0)
 
5502
                BufferTooShort();
 
5503
            sendString(buf);
 
5504
 
 
5505
            printBar(buf, sizeof(buf), el->actBandwidthUsageS, el->actBandwidthUsageR, maxBandwidthUsage, 3);
 
5506
 
 
5507
            if(snprintf(buf, sizeof(buf), "<TD "TD_BG" ALIGN=RIGHT>%s</TD>", tmpName2) < 0)
 
5508
                BufferTooShort();
 
5509
            sendString(buf);
 
5510
 
 
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)
 
5514
                BufferTooShort();
 
5515
            sendString(buf);
 
5516
 
 
5517
            sendString("</TR>\n");
 
5518
            printedEntries++;
 
5519
            
 
5520
            /* Avoid huge tables */
 
5521
            if(printedEntries > myGlobals.maxNumLines)
 
5522
                break;
 
5523
        } else {
 
5524
            traceEvent(CONST_TRACE_WARNING, "quicksort() problem!");
 
5525
        }
 
5526
    }
 
5527
    sendString("</TABLE>"TABLE_OFF"<P>\n");
 
5528
    sendString("</CENTER>\n");
 
5529
    
 
5530
    printFooterHostLink();
 
5531
    
 
5532
    printBandwidthFooter();   
 
5533
 
 
5534
    addPageIndicator(CONST_HOSTS_INFO_HTML, pageNum, numEntries,
 
5535
                     myGlobals.maxNumLines, revertOrder, abs(sortedColumn));
 
5536
 
 
5537
    free(tmpTable);
 
5538
}
 
5539
 
 
5540
/* ************************************ */
 
5541
 
 
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];
 
5556
  
 
5557
    printHTMLheader("FibreChannel Per Port Traffic", 0, 0);
 
5558
 
 
5559
    maxHosts = myGlobals.device[myGlobals.actualReportDeviceId].hostsno; /* save it as it can change */
 
5560
 
 
5561
    tmpTable = (HostTraffic**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize*sizeof(HostTraffic*), "printFcAccounting");
 
5562
    if(tmpTable == NULL)
 
5563
      return;
 
5564
 
 
5565
    if(revertOrder) {
 
5566
        sign = "";
 
5567
        arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
5568
    } else {
 
5569
        sign = "-";
 
5570
        arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
5571
    }
 
5572
 
 
5573
    totalBytesSent=0, totalBytesRcvd=0;
 
5574
 
 
5575
    for(el=getFirstHost(myGlobals.actualReportDeviceId);
 
5576
        el != NULL; el = getNextHost(myGlobals.actualReportDeviceId, el)) {
 
5577
        if (!isFcHost (el)) continue;
 
5578
 
 
5579
        /* Skip Control VSAN traffic */
 
5580
        if (el->vsanId > MAX_USER_VSAN) continue;
 
5581
        
 
5582
        if((el->fcBytesSent.value > 0) || (el->fcBytesRcvd.value > 0)) {
 
5583
            tmpTable[numEntries++]=el;
 
5584
            totalBytesSent += el->fcBytesSent.value;
 
5585
            totalBytesRcvd += el->fcBytesRcvd.value;
 
5586
        }
 
5587
        if(numEntries >= maxHosts) break;
 
5588
    }
 
5589
 
 
5590
    if(numEntries <= 0) {
 
5591
        printNoDataYet();
 
5592
        free(tmpTable);
 
5593
        return;
 
5594
    }
 
5595
 
 
5596
    myGlobals.columnSort = sortedColumn;
 
5597
    qsort(tmpTable, numEntries, sizeof(struct hostTraffic*), cmpHostsFctn);
 
5598
 
 
5599
    if(snprintf(htmlAnchor, sizeof(htmlAnchor),
 
5600
                "<a href=\"" CONST_FC_TRAFFIC_HTML "?col=%s", sign) < 0)
 
5601
        BufferTooShort();
 
5602
    if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
 
5603
                "<a href=\"" CONST_FC_TRAFFIC_HTML "?col=") < 0)
 
5604
        BufferTooShort();
 
5605
 
 
5606
    for (i = 1; i < 6; i++) {
 
5607
        if (abs (myGlobals.columnSort) == i) {
 
5608
            arrow[i] = arrowGif;
 
5609
            theAnchor[i] = htmlAnchor;
 
5610
        }
 
5611
        else {
 
5612
            arrow[i] = "";
 
5613
            theAnchor[i] = htmlAnchor1;
 
5614
        }
 
5615
    }
 
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&nbsp;Sent%s</a></TH>"
 
5622
                "<TH "TH_BG" COLSPAN=2 "DARK_BG">%s4\">Bytes&nbsp;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)
 
5627
        BufferTooShort();
 
5628
 
 
5629
    sendString(buf);
 
5630
 
 
5631
    for(idx=pageNum*myGlobals.maxNumLines; idx<numEntries; idx++) {
 
5632
 
 
5633
        if(revertOrder)
 
5634
            el = tmpTable[numEntries-idx-1];
 
5635
        else
 
5636
            el = tmpTable[idx];
 
5637
 
 
5638
        if(el != NULL) {
 
5639
            char *tmpName1;
 
5640
            strncpy (tmpbuf, (char *)el->hostNumFcAddress,
 
5641
                     LEN_FC_ADDRESS_DISPLAY);
 
5642
            tmpName1 = tmpbuf;
 
5643
 
 
5644
            a = el->fcBytesSent.value;
 
5645
            b = el->fcBytesRcvd.value;
 
5646
 
 
5647
            if(a < 100)  /* Avoid very small decimal values */
 
5648
                sentpct = 0;
 
5649
            else
 
5650
                sentpct = (100*(float)a)/totalBytesSent;
 
5651
 
 
5652
            if(b < 100)  /* Avoid very small decimal values */
 
5653
                rcvdpct = 0;
 
5654
            else
 
5655
                rcvdpct = (100*(float)b)/totalBytesRcvd;
 
5656
 
 
5657
            if(snprintf(buf, sizeof(buf), "<TR "TR_ON" %s>"
 
5658
                        "%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",
 
5662
                        getRowColor(),
 
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)),
 
5667
                        tmpName1,
 
5668
                        formatBytes(a, 1, formatBuf[0], 32),
 
5669
                        sentpct, myGlobals.separator,
 
5670
                        formatBytes(b, 1, formatBuf[1], 32),
 
5671
                        rcvdpct, myGlobals.separator) < 0)
 
5672
                BufferTooShort();
 
5673
            sendString(buf);
 
5674
 
 
5675
            /* Avoid huge tables */
 
5676
            if(printedEntries++ > myGlobals.maxNumLines)
 
5677
                break;
 
5678
        }
 
5679
    }
 
5680
 
 
5681
    sendString("</TABLE>"TABLE_OFF"\n");
 
5682
 
 
5683
    addPageIndicator(CONST_FC_TRAFFIC_HTML, pageNum, numEntries, myGlobals.maxNumLines,
 
5684
                     revertOrder, abs(sortedColumn));
 
5685
 
 
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");
 
5689
 
 
5690
    totalBytes = totalBytesSent+totalBytesRcvd;
 
5691
 
 
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)
 
5698
        BufferTooShort();
 
5699
 
 
5700
    sendString(buf);
 
5701
    sendString("</TABLE>"TABLE_OFF"\n");
 
5702
    sendString("</CENTER>\n");
 
5703
 
 
5704
    printFooterHostLink();
 
5705
 
 
5706
    free(tmpTable);
 
5707
}
 
5708
 
 
5709
/* ********************************** */
 
5710
 
 
5711
int printScsiSessionBytes (int actualDeviceId, int sortedColumn, int revertOrder,
 
5712
                           int pageNum, char *url, HostTraffic *el) {
 
5713
    int idx, j, i;
 
5714
    int numSessions, printedSessions, skipSessions;
 
5715
    ScsiSessionSortEntry *tmpTable, *entry;
 
5716
    FCSession *session;
 
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];
 
5723
    char pageUrl[64];
 
5724
 
 
5725
    printHTMLheader("SCSI Sessions: Bytes", 0, 0);
 
5726
 
 
5727
    if(!myGlobals.enableSessionHandling) {
 
5728
        printNotAvailable("-z or --disable-sessions");
 
5729
        return 0;
 
5730
    }
 
5731
 
 
5732
    /* We have to allocate as many entries as there are sessions and LUNs
 
5733
     * within a session.
 
5734
     */
 
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");
 
5738
        return 0;
 
5739
    }
 
5740
 
 
5741
    memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
 
5742
 
 
5743
    for(i=strlen(url); i>0; i--)
 
5744
        if(url[i] == '?') {
 
5745
            url[i] = '\0';
 
5746
            break;
 
5747
        }
 
5748
      
 
5749
    urlFixupToRFC1945Inplace(url);
 
5750
 
 
5751
#ifdef CFG_MULTITHREADED
 
5752
    accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionBytes");
 
5753
#endif
 
5754
 
 
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) {
 
5759
 
 
5760
            if (session->magic != CONST_MAGIC_NUMBER) {
 
5761
                traceEvent (CONST_TRACE_ERROR, "printScsiSessions: Invalid session magic\n");
 
5762
                break;
 
5763
            }
 
5764
            if (session->fcpBytesSent.value || session->fcpBytesRcvd.value) {
 
5765
                if ((el && ((session->initiator  == el)
 
5766
                            || (session->remotePeer == el)))
 
5767
                    || (el == NULL)) {
 
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];
 
5777
                            }
 
5778
                            if (j > session->lunMax)
 
5779
                                break;
 
5780
                        }
 
5781
                    }
 
5782
                    if ((session->unknownLunBytesSent.value ||
 
5783
                         session->unknownLunBytesRcvd.value)) {
 
5784
                        if ((el && ((session->initiator  == el)
 
5785
                                    || (session->remotePeer == el)))
 
5786
                            || (el == NULL)) {
 
5787
                            tmpTable[numSessions].initiator = session->initiator;
 
5788
                            tmpTable[numSessions].target = session->remotePeer;
 
5789
                            tmpTable[numSessions].lun = 0xFFFF;
 
5790
                            tmpTable[numSessions++].stats = (ScsiLunTrafficInfo *)session;
 
5791
                        }
 
5792
                    }
 
5793
                }
 
5794
            }
 
5795
            session = session->next;
 
5796
        }
 
5797
    }
 
5798
 
 
5799
    if(numSessions > 0) {
 
5800
 
 
5801
        if(revertOrder) {
 
5802
            sign = "";
 
5803
            arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
5804
        } else {
 
5805
            sign = "-";
 
5806
            arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
5807
        }
 
5808
 
 
5809
        myGlobals.columnSort = sortedColumn;
 
5810
        qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
 
5811
 
 
5812
        if (el == NULL) {
 
5813
            if (strcmp (url, CONST_SCSI_BYTES_HTML) == 0) {
 
5814
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
 
5815
                    BufferTooShort();
 
5816
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
 
5817
                    BufferTooShort();
 
5818
                if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
 
5819
                    BufferTooShort();
 
5820
            }
 
5821
            else {
 
5822
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
 
5823
                    BufferTooShort();
 
5824
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
 
5825
                    BufferTooShort();
 
5826
                if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
 
5827
                    BufferTooShort();
 
5828
            }
 
5829
        }
 
5830
        else {
 
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)
 
5835
                BufferTooShort();
 
5836
            if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
 
5837
                        "<A HREF=/%s.html?showF=%d&page=%d&col=", url,
 
5838
                        showHostScsiSessionBytes, pageNum) < 0)
 
5839
                BufferTooShort();
 
5840
            if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
 
5841
                          url, showHostScsiSessionBytes) < 0)
 
5842
                BufferTooShort();
 
5843
        }
 
5844
 
 
5845
        for (i = 1; i < 48; i++) {
 
5846
            
 
5847
            if(abs(myGlobals.columnSort) == i) {
 
5848
                arrow[i] = arrowGif;
 
5849
                theAnchor[i] = htmlAnchor;
 
5850
            } else {
 
5851
                arrow[i] = "";
 
5852
                theAnchor[i] = htmlAnchor1;
 
5853
            }
 
5854
        }
 
5855
    }
 
5856
    else {
 
5857
#ifdef CFG_MULTITHREADED
 
5858
       releaseMutex(&myGlobals.fcSessionsMutex);
 
5859
#endif
 
5860
       printNoDataYet ();
 
5861
       free (tmpTable);
 
5862
       return 0;
 
5863
    }
 
5864
 
 
5865
#ifdef CFG_MULTITHREADED
 
5866
    releaseMutex(&myGlobals.fcSessionsMutex);
 
5867
#endif
 
5868
 
 
5869
    /*
 
5870
      Due to the way sessions are handled, sessions before those to
 
5871
      display need to be skipped
 
5872
    */
 
5873
    printedSessions = 0;
 
5874
    skipSessions = 0;
 
5875
    for (idx = 0; idx < numSessions; idx++) {
 
5876
        Counter dataSent, dataRcvd;
 
5877
 
 
5878
        if(revertOrder)
 
5879
            entry = &tmpTable[numSessions-idx-1];
 
5880
        else
 
5881
            entry = &tmpTable[idx];
 
5882
 
 
5883
        if (entry == NULL) {
 
5884
            continue;
 
5885
        }
 
5886
        
 
5887
        if (printedSessions < myGlobals.maxNumLines) {
 
5888
 
 
5889
            if(el
 
5890
               && (entry->initiator  != el)
 
5891
               && (entry->target != el)) {
 
5892
                continue;
 
5893
            }
 
5894
 
 
5895
            if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
 
5896
                continue;
 
5897
            }
 
5898
            
 
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&nbsp;Bytes</TH>"
 
5908
                             "<TH "TH_BG" "DARK_BG" COLSPAN=3>Data&nbsp;Bytes</TH>"
 
5909
                             "<TH "TH_BG" "DARK_BG" COLSPAN=2>Rd&nbsp;Size(Blks)</TH>"
 
5910
                             "<TH "TH_BG" "DARK_BG" COLSPAN=2>Wr&nbsp;Size(Blks)</TH>"
 
5911
                             "<TH "TH_BG" "DARK_BG" COLSPAN=2>Xfer&nbsp;Rdy&nbsp;Size</TH>"
 
5912
                             "<TH "TH_BG" "DARK_BG" COLSPAN=2>IOPS</TH>"
 
5913
                             "</TR>\n",
 
5914
                             theAnchor[1], arrow[1],
 
5915
                             theAnchor[2], arrow[2],
 
5916
                             theAnchor[3], arrow[3]
 
5917
                        ) < 0) BufferTooShort ();
 
5918
                sendString (buf);
 
5919
        
 
5920
                if (snprintf(buf, sizeof (buf),
 
5921
                             "<TR "TR_ON" %s>"
 
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>"
 
5935
                             "</TR>\n",
 
5936
                             getRowColor(),
 
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]
 
5950
                        ) < 0)
 
5951
                    BufferTooShort();
 
5952
        
 
5953
                sendString(buf);
 
5954
        
 
5955
            }
 
5956
 
 
5957
            if (entry->lun != 0xFFFF) {
 
5958
                dataSent = entry->stats->bytesSent.value;
 
5959
                dataRcvd = entry->stats->bytesRcvd.value;
 
5960
                
 
5961
                /* Sanity check */
 
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>"
 
5980
                            "</TR>\n",
 
5981
                            getRowColor(),
 
5982
                            makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
 
5983
                                          sizeof (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)),
 
5990
                            entry->lun,
 
5991
                            formatBytes(dataSent, 1, formatBuf[0], 32),
 
5992
                            formatBytes(dataRcvd, 1, formatBuf[1], 32),
 
5993
                            formatBytes (entry->stats->scsiRdBytes.value, 1,
 
5994
                                         formatBuf[2], 32),
 
5995
                            formatBytes (entry->stats->scsiWrBytes.value, 1,
 
5996
                                         formatBuf[3], 32),
 
5997
                            formatBytes (entry->stats->scsiOtBytes.value, 1,
 
5998
                                         formatBuf[4], 32),
 
5999
                            entry->stats->minRdSize,
 
6000
                            entry->stats->maxRdSize,
 
6001
                            entry->stats->minWrSize,
 
6002
                            entry->stats->maxWrSize,
 
6003
                            formatBytes (entry->stats->minXferRdySize, 1,
 
6004
                                         formatBuf[5], 32),
 
6005
                            formatBytes (entry->stats->maxXferRdySize, 1,
 
6006
                                         formatBuf[6], 32),
 
6007
                            entry->stats->minIops,
 
6008
                            entry->stats->maxIops
 
6009
                       ) < 0) BufferTooShort();
 
6010
            }
 
6011
            else {
 
6012
                /* Unknown LUN data */
 
6013
                session = (FCSession *)entry->stats;
 
6014
                
 
6015
                /* Sanity check */
 
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>"
 
6034
                            "</TR>\n",
 
6035
                            getRowColor(),
 
6036
                            makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
 
6037
                                          sizeof (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)),
 
6044
                            "N/A",
 
6045
                            formatBytes(session->unknownLunBytesSent.value, 1,
 
6046
                                        formatBuf[0], 32),
 
6047
                            formatBytes(session->unknownLunBytesRcvd.value, 1,
 
6048
                                        formatBuf[1], 32),
 
6049
                            "N/A",
 
6050
                            "N/A",
 
6051
                            "N/A",
 
6052
                            "N/A",
 
6053
                            "N/A",
 
6054
                            "N/A",
 
6055
                            "N/A",
 
6056
                            "N/A",
 
6057
                            "N/A",
 
6058
                            "N/A",
 
6059
                            "N/A"
 
6060
                       ) < 0) BufferTooShort();
 
6061
            }
 
6062
            
 
6063
            sendString(buf);
 
6064
            printedSessions++;
 
6065
        }
 
6066
    }
 
6067
    
 
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);
 
6074
 
 
6075
        printFooterHostLink();
 
6076
    } else {
 
6077
        if(el == NULL) {
 
6078
            printFlagedWarning("<I>No SCSI Sessions</I>");
 
6079
        }
 
6080
    }
 
6081
 
 
6082
    free (tmpTable);
 
6083
    return (printedSessions);
 
6084
}
 
6085
 
 
6086
/* ********************************** */
 
6087
 
 
6088
int printScsiSessionTimes (int actualDeviceId, int sortedColumn, int revertOrder,
 
6089
                           int pageNum, char *url, HostTraffic *el) {
 
6090
    int idx, j, i;
 
6091
    int numSessions, printedSessions, skipSessions;
 
6092
    unsigned long duration;
 
6093
    ScsiSessionSortEntry *tmpTable, *entry;
 
6094
    FCSession *session;
 
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];
 
6101
 
 
6102
    printHTMLheader("SCSI Sessions: Times", 0, 0);
 
6103
 
 
6104
    if(!myGlobals.enableSessionHandling) {
 
6105
        printNotAvailable("-z or --disable-sessions");
 
6106
        return 0;
 
6107
    }
 
6108
 
 
6109
    /* We have to allocate as many entries as there are sessions and LUNs
 
6110
     * within a session.
 
6111
     */
 
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");
 
6115
        return 0;
 
6116
    }
 
6117
 
 
6118
    memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
 
6119
    
 
6120
    for(i=strlen(url); i>0; i--)
 
6121
        if(url[i] == '?') {
 
6122
            url[i] = '\0';
 
6123
            break;
 
6124
        }
 
6125
      
 
6126
    urlFixupFromRFC1945Inplace(url);
 
6127
 
 
6128
#ifdef CFG_MULTITHREADED
 
6129
    accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionTimes");
 
6130
#endif
 
6131
 
 
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");
 
6138
                break;
 
6139
            }
 
6140
            if (session->fcpBytesSent.value || session->fcpBytesRcvd.value) {
 
6141
                if ((el && ((session->initiator  == el)
 
6142
                            || (session->remotePeer == el)))
 
6143
                    || (el == NULL)) {
 
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];
 
6153
                            }
 
6154
                            if (j > session->lunMax)
 
6155
                                break;
 
6156
                        }
 
6157
                    }
 
6158
                    /* Don't care about unknown LUN info as we don't gather
 
6159
                     * anything but bytes for such traffic.
 
6160
                     */
 
6161
                }
 
6162
            }
 
6163
            session = session->next;
 
6164
        }
 
6165
    }
 
6166
 
 
6167
    if(numSessions > 0) {
 
6168
 
 
6169
        if(revertOrder) {
 
6170
            sign = "";
 
6171
            arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
6172
        } else {
 
6173
            sign = "-";
 
6174
            arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
6175
        }
 
6176
 
 
6177
        myGlobals.columnSort = sortedColumn;
 
6178
        qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
 
6179
 
 
6180
        if (el == NULL) {
 
6181
            if (strcmp (url, CONST_SCSI_TIMES_HTML) == 0) {
 
6182
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
 
6183
                    BufferTooShort();
 
6184
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
 
6185
                    BufferTooShort();
 
6186
                if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
 
6187
                    BufferTooShort();
 
6188
            }
 
6189
            else {
 
6190
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
 
6191
                    BufferTooShort();
 
6192
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
 
6193
                    BufferTooShort();
 
6194
                if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
 
6195
                    BufferTooShort();
 
6196
            }
 
6197
        }
 
6198
        else {
 
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)
 
6203
                BufferTooShort();
 
6204
            if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
 
6205
                        "<A HREF=/%s.html?showF=%d&page=%d&col=", url,
 
6206
                        showHostScsiSessionTimes, pageNum) < 0)
 
6207
                BufferTooShort();
 
6208
            if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
 
6209
                          url, showHostScsiSessionTimes) < 0)
 
6210
                BufferTooShort();
 
6211
        }
 
6212
 
 
6213
        for (i = 1; i < 48; i++) {
 
6214
            if(abs(myGlobals.columnSort) == i) {
 
6215
                arrow[i] = arrowGif;
 
6216
                theAnchor[i] = htmlAnchor;
 
6217
            } else {
 
6218
                arrow[i] = "";
 
6219
                theAnchor[i] = htmlAnchor1;
 
6220
            }
 
6221
        }
 
6222
    }
 
6223
    else {
 
6224
#ifdef CFG_MULTITHREADED
 
6225
    releaseMutex(&myGlobals.fcSessionsMutex);
 
6226
#endif
 
6227
        printNoDataYet();
 
6228
        free (tmpTable);
 
6229
        return 0;
 
6230
    }
 
6231
 
 
6232
#ifdef CFG_MULTITHREADED
 
6233
    releaseMutex(&myGlobals.fcSessionsMutex);
 
6234
#endif
 
6235
    /*
 
6236
      Due to the way sessions are handled, sessions before those to
 
6237
      display need to be skipped
 
6238
    */
 
6239
    printedSessions = skipSessions = 0;
 
6240
    for (idx = 0; idx < numSessions; idx++) {
 
6241
 
 
6242
        if(revertOrder)
 
6243
            entry = &tmpTable[numSessions-idx-1];
 
6244
        else
 
6245
            entry = &tmpTable[idx];
 
6246
 
 
6247
        if (entry == NULL) {
 
6248
            continue;
 
6249
        }
 
6250
        
 
6251
        if (printedSessions < myGlobals.maxNumLines) {
 
6252
 
 
6253
            if(el
 
6254
               && (entry->initiator  != el)
 
6255
               && (entry->target != el)) {
 
6256
                continue;
 
6257
            }
 
6258
 
 
6259
            if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
 
6260
                continue;
 
6261
            }
 
6262
            
 
6263
            if(printedSessions == 0) {
 
6264
                sendString("<CENTER>\n");
 
6265
 
 
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&nbsp;RTT</TH>"
 
6273
                             "<TH "TH_BG" "DARK_BG" COLSPAN=2>Cmd-XFR_RDY&nbsp;RTT</TH>"
 
6274
                             "<TH "TH_BG" "DARK_BG" COLSPAN=2>Cmd-Data&nbsp;RTT(Rd)</TH>"
 
6275
                             "<TH "TH_BG" "DARK_BG" COLSPAN=2>Cmd-Data&nbsp;RTT(Wr)</TH>"
 
6276
                             "<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s26>Active&nbsp;Since%s</A></TH>"
 
6277
                             "<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s27>Last&nbsp;Seen%s</A></TH>"
 
6278
                             "</TR>\n",
 
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 ();
 
6285
                sendString (buf);
 
6286
 
 
6287
                if (snprintf(buf, sizeof (buf),
 
6288
                             "<TR "TR_ON" %s>"
 
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>"
 
6297
                             "</TR>\n",
 
6298
                             getRowColor(),
 
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]
 
6307
                        ) < 0)
 
6308
                    BufferTooShort();
 
6309
                        
 
6310
                sendString(buf);
 
6311
 
 
6312
            }
 
6313
            
 
6314
            /* Sanity check */
 
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>"
 
6330
                        "</TR>\n",
 
6331
                        getRowColor(),
 
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)),
 
6340
                        entry->lun,
 
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();
 
6362
                
 
6363
            sendString(buf);
 
6364
            printedSessions++;
 
6365
        }
 
6366
    }
 
6367
    
 
6368
    if (printedSessions > 0) {
 
6369
        sendString("</TABLE>"TABLE_OFF"<P>\n");
 
6370
        sendString("</CENTER>\n");
 
6371
 
 
6372
        addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.maxNumLines,
 
6373
                         revertOrder, sortedColumn);
 
6374
 
 
6375
        printFooterHostLink();
 
6376
    } else {
 
6377
        if(el == NULL) {
 
6378
            printFlagedWarning("<I>No SCSI Sessions</I>");
 
6379
        }
 
6380
    }
 
6381
 
 
6382
    free (tmpTable);
 
6383
    return (printedSessions);
 
6384
}
 
6385
 
 
6386
/* ********************************** */
 
6387
 
 
6388
int printScsiSessionStatusInfo (int actualDeviceId, int sortedColumn,
 
6389
                                int revertOrder, int pageNum, char *url,
 
6390
                                HostTraffic *el) {
 
6391
    int idx, j, i;
 
6392
    int numSessions, printedSessions, skipSessions;
 
6393
    ScsiSessionSortEntry *tmpTable, *entry;
 
6394
    FCSession *session;
 
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];
 
6401
 
 
6402
    printHTMLheader("SCSI Sessions: Status Info", 0, 0);
 
6403
 
 
6404
    if(!myGlobals.enableSessionHandling) {
 
6405
        printNotAvailable("-z or --disable-sessions");
 
6406
        return 0;
 
6407
    }
 
6408
 
 
6409
    /* We have to allocate as many entries as there are sessions and LUNs
 
6410
     * within a session.
 
6411
     */
 
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");
 
6415
        return 0;
 
6416
    }
 
6417
 
 
6418
    memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
 
6419
    
 
6420
    for(i=strlen(url); i>0; i--)
 
6421
        if(url[i] == '?') {
 
6422
            url[i] = '\0';
 
6423
            break;
 
6424
        }
 
6425
      
 
6426
    urlFixupFromRFC1945Inplace(url);
 
6427
 
 
6428
#ifdef CFG_MULTITHREADED
 
6429
    accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionStatusInfo");
 
6430
#endif
 
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");
 
6437
                break;
 
6438
            }
 
6439
            if (session->fcpBytesSent.value || session->fcpBytesRcvd.value) {
 
6440
                if ((el && ((session->initiator  == el)
 
6441
                            || (session->remotePeer == el)))
 
6442
                    || (el == NULL)) {
 
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];
 
6452
                            }
 
6453
                            if (j > session->lunMax)
 
6454
                                break;
 
6455
                        }
 
6456
                    }
 
6457
                }
 
6458
            }
 
6459
            session = session->next;
 
6460
        }
 
6461
    }
 
6462
 
 
6463
    if(numSessions > 0) {
 
6464
 
 
6465
        if(revertOrder) {
 
6466
            sign = "";
 
6467
            arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
6468
        } else {
 
6469
            sign = "-";
 
6470
            arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
6471
        }
 
6472
 
 
6473
        myGlobals.columnSort = sortedColumn;
 
6474
        qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
 
6475
 
 
6476
        if (el == NULL) {
 
6477
            if (strcmp (url, CONST_SCSI_STATUS_HTML) == 0) {
 
6478
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
 
6479
                    BufferTooShort();
 
6480
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
 
6481
                    BufferTooShort();
 
6482
                if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
 
6483
                    BufferTooShort();
 
6484
            }
 
6485
            else {
 
6486
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
 
6487
                    BufferTooShort();
 
6488
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
 
6489
                    BufferTooShort();
 
6490
                if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
 
6491
                    BufferTooShort();
 
6492
            }
 
6493
        }
 
6494
        else {
 
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)
 
6499
                BufferTooShort();
 
6500
            if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
 
6501
                        "<A HREF=/%s.html?showF=%d&page=%d&col=", url,
 
6502
                        showHostScsiSessionStatus, pageNum) < 0)
 
6503
                BufferTooShort();
 
6504
            if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
 
6505
                          url, showHostScsiSessionStatus) < 0)
 
6506
                BufferTooShort();
 
6507
        }
 
6508
 
 
6509
        for (i = 1; i < 48; i++) {
 
6510
            if(abs(myGlobals.columnSort) == i) {
 
6511
                arrow[i] = arrowGif;
 
6512
                theAnchor[i] = htmlAnchor;
 
6513
            } else {
 
6514
                arrow[i] = "";
 
6515
                theAnchor[i] = htmlAnchor1;
 
6516
            }
 
6517
        }
 
6518
    }
 
6519
    else {
 
6520
#ifdef CFG_MULTITHREADED
 
6521
    releaseMutex(&myGlobals.fcSessionsMutex);
 
6522
#endif
 
6523
        printNoDataYet();
 
6524
        free (tmpTable);
 
6525
        return 0;
 
6526
    }
 
6527
#ifdef CFG_MULTITHREADED
 
6528
    releaseMutex(&myGlobals.fcSessionsMutex);
 
6529
#endif
 
6530
    /*
 
6531
      Due to the way sessions are handled, sessions before those to
 
6532
      display need to be skipped
 
6533
    */
 
6534
    printedSessions = skipSessions = 0;
 
6535
    for (idx = 0; idx < numSessions; idx++) {
 
6536
 
 
6537
        if(revertOrder)
 
6538
            entry = &tmpTable[numSessions-idx-1];
 
6539
        else
 
6540
            entry = &tmpTable[idx];
 
6541
 
 
6542
        if (entry == NULL) {
 
6543
            continue;
 
6544
        }
 
6545
        
 
6546
        if (printedSessions < myGlobals.maxNumLines) {
 
6547
 
 
6548
            if(el
 
6549
               && (entry->initiator  != el)
 
6550
               && (entry->target != el)) {
 
6551
                continue;
 
6552
            }
 
6553
 
 
6554
            if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
 
6555
                continue;
 
6556
            }
 
6557
            
 
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>#&nbsp;Failed&nbsp;Cmds%s</A></TH>"
 
6567
                             "<TH "TH_BG" "DARK_BG">%s28>#&nbsp;Check Condition%s</A></TH>"
 
6568
                             "<TH "TH_BG" "DARK_BG">%s29>#&nbsp;Busy%s</A></TH>"
 
6569
                             "<TH "TH_BG" "DARK_BG">%s30>#&nbsp;Reservation&nbsp;Conflict%s</A></TH>"
 
6570
                             "<TH "TH_BG" "DARK_BG">%s31>#&nbsp;Task Set Full%s</A></TH>"
 
6571
                             "<TH "TH_BG" "DARK_BG">%s32>#&nbsp;Task Aborts%s</A></TH>"
 
6572
                             "</TR>\n",
 
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 ();
 
6583
                sendString (buf);
 
6584
            }
 
6585
            
 
6586
            /* Sanity check */
 
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>"
 
6598
                        "</TR>\n",
 
6599
                        getRowColor(),
 
6600
                        makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
 
6601
                                      sizeof (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)),
 
6608
                        entry->lun,
 
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();
 
6616
                
 
6617
            sendString(buf);
 
6618
            printedSessions++;
 
6619
        }
 
6620
    }
 
6621
    
 
6622
    if (printedSessions > 0) {
 
6623
        sendString("</TABLE>"TABLE_OFF"<P>\n");
 
6624
        sendString("</CENTER>\n");
 
6625
 
 
6626
        addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.maxNumLines,
 
6627
                         revertOrder, sortedColumn);
 
6628
 
 
6629
        printFooterHostLink();
 
6630
    } else {
 
6631
        if(el == NULL) {
 
6632
            printFlagedWarning("<I>No SCSI Sessions</I>");
 
6633
        }
 
6634
    }
 
6635
 
 
6636
    free (tmpTable);
 
6637
    return (printedSessions);
 
6638
}
 
6639
 
 
6640
int printScsiSessionTmInfo (int actualDeviceId, int sortedColumn,
 
6641
                            int revertOrder, int pageNum, char *url,
 
6642
                            HostTraffic *el)
 
6643
{
 
6644
    int idx, j, i;
 
6645
    int numSessions, printedSessions, skipSessions, total;
 
6646
    ScsiSessionSortEntry *tmpTable, *entry;
 
6647
    FCSession *session;
 
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];
 
6654
 
 
6655
    printHTMLheader("SCSI Sessions: Task Management Info", 0, 0);
 
6656
 
 
6657
    if(!myGlobals.enableSessionHandling) {
 
6658
        printNotAvailable("-z or --disable-sessions");
 
6659
        return 0;
 
6660
    }
 
6661
 
 
6662
    /* We have to allocate as many entries as there are sessions and LUNs
 
6663
     * within a session.
 
6664
     */
 
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");
 
6668
        return 0;
 
6669
    }
 
6670
 
 
6671
    memset (tmpTable, 0, myGlobals.device[actualDeviceId].numFcSessions*MAX_LUNS_SUPPORTED*sizeof(ScsiSessionSortEntry));
 
6672
    
 
6673
    for(i=strlen(url); i>0; i--)
 
6674
        if(url[i] == '?') {
 
6675
            url[i] = '\0';
 
6676
            break;
 
6677
        }
 
6678
      
 
6679
    urlFixupFromRFC1945Inplace(url);
 
6680
 
 
6681
#ifdef CFG_MULTITHREADED
 
6682
    accessMutex(&myGlobals.fcSessionsMutex, "printScsiSessionTmInfo");
 
6683
#endif
 
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");
 
6690
                break;
 
6691
            }
 
6692
            
 
6693
            if ((session->fcpBytesRcvd.value) || (session->fcpBytesSent.value)) {
 
6694
                if ((el && ((session->initiator  == el)
 
6695
                            || (session->remotePeer == el)))
 
6696
                    || (el == NULL)) {
 
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];
 
6706
                            }
 
6707
                            if (j > session->lunMax)
 
6708
                                break;
 
6709
                        }
 
6710
                    }
 
6711
                }
 
6712
            }
 
6713
            session = session->next;
 
6714
        }
 
6715
    }
 
6716
 
 
6717
    if(numSessions > 0) {
 
6718
 
 
6719
        if(revertOrder) {
 
6720
            sign = "";
 
6721
            arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
6722
        } else {
 
6723
            sign = "-";
 
6724
            arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
6725
        }
 
6726
 
 
6727
        myGlobals.columnSort = sortedColumn;
 
6728
        qsort (tmpTable, numSessions, sizeof (ScsiSessionSortEntry), cmpScsiSessionsFctn);
 
6729
 
 
6730
        if (el == NULL) {
 
6731
            if (strcmp (url, CONST_SCSI_TM_HTML) == 0) {
 
6732
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
 
6733
                    BufferTooShort();
 
6734
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
 
6735
                    BufferTooShort();
 
6736
                if (snprintf (pageUrl, sizeof (pageUrl), "%s", url) < 0)
 
6737
                    BufferTooShort();
 
6738
            }
 
6739
            else {
 
6740
                if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
 
6741
                    BufferTooShort();
 
6742
                if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
 
6743
                    BufferTooShort();
 
6744
                if (snprintf (pageUrl, sizeof (pageUrl), "%s.html", url) < 0)
 
6745
                    BufferTooShort();
 
6746
            }
 
6747
        }
 
6748
        else {
 
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)
 
6753
                BufferTooShort();
 
6754
            if(snprintf(htmlAnchor1, sizeof(htmlAnchor1),
 
6755
                        "<A HREF=/%s.html?showF=%d&page=%d&col=", url,
 
6756
                        showHostScsiSessionTMInfo, pageNum) < 0)
 
6757
                BufferTooShort();
 
6758
            if (snprintf (pageUrl, sizeof (pageUrl), "%s.html?showF=%d",
 
6759
                          url, showHostScsiSessionTMInfo) < 0)
 
6760
                BufferTooShort();
 
6761
        }
 
6762
 
 
6763
        for (i = 1; i < 48; i++) {
 
6764
            if(abs(myGlobals.columnSort) == i) {
 
6765
                arrow[i] = arrowGif;
 
6766
                theAnchor[i] = htmlAnchor;
 
6767
            } else {
 
6768
                arrow[i] = "";
 
6769
                theAnchor[i] = htmlAnchor1;
 
6770
            }
 
6771
        }
 
6772
    }
 
6773
    else {
 
6774
#ifdef CFG_MULTITHREADED
 
6775
    releaseMutex(&myGlobals.fcSessionsMutex);
 
6776
#endif
 
6777
        printNoDataYet();
 
6778
        free (tmpTable);
 
6779
        return 0;
 
6780
    }
 
6781
 
 
6782
#ifdef CFG_MULTITHREADED
 
6783
    releaseMutex(&myGlobals.fcSessionsMutex);
 
6784
#endif
 
6785
    /*
 
6786
      Due to the way sessions are handled, sessions before those to
 
6787
      display need to be skipped
 
6788
    */
 
6789
    printedSessions = skipSessions = 0;
 
6790
    for (idx = 0; idx < numSessions; idx++) {
 
6791
 
 
6792
        if(revertOrder)
 
6793
            entry = &tmpTable[numSessions-idx-1];
 
6794
        else
 
6795
            entry = &tmpTable[idx];
 
6796
 
 
6797
        if (entry == NULL) {
 
6798
            continue;
 
6799
        }
 
6800
        
 
6801
        if (printedSessions < myGlobals.maxNumLines) {
 
6802
 
 
6803
            if(el
 
6804
               && (entry->initiator  != el)
 
6805
               && (entry->target != el)) {
 
6806
                continue;
 
6807
            }
 
6808
 
 
6809
            if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
 
6810
                continue;
 
6811
            }
 
6812
            
 
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>#&nbsp;Abort Task Set%s</A></TH>"
 
6822
                             "<TH "TH_BG" "DARK_BG">%s34>#&nbsp;Clear Task Set%s</A></TH>"
 
6823
                             "<TH "TH_BG" "DARK_BG">%s35>#&nbsp;Clear ACA%s</A></TH>"
 
6824
                             "<TH "TH_BG" "DARK_BG">%s36>#&nbsp;Target Reset%s</A></TH>"
 
6825
                             "<TH "TH_BG" "DARK_BG">%s37>#&nbsp;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>"
 
6828
                             "</TR>\n",
 
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 ();
 
6840
                sendString (buf);
 
6841
            }
 
6842
            
 
6843
            /* Sanity check */
 
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>"
 
6856
                        "</TR>\n",
 
6857
                        getRowColor(),
 
6858
                        makeVsanLink (entry->initiator->vsanId, 0, vsanBuf,
 
6859
                                      sizeof (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)),
 
6866
                        entry->lun,
 
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),
 
6873
                                   formatBuf[0], 32),
 
6874
                        formatTime((time_t *)&(entry->stats->lastLunRstTime),
 
6875
                                   formatBuf[1], 32)
 
6876
                   ) < 0) BufferTooShort();
 
6877
                
 
6878
            sendString(buf);
 
6879
            printedSessions++;
 
6880
        }
 
6881
    }
 
6882
    
 
6883
    if (printedSessions > 0) {
 
6884
        sendString("</TABLE>"TABLE_OFF"<P>\n");
 
6885
        sendString("</CENTER>\n");
 
6886
 
 
6887
        addPageIndicator(pageUrl, pageNum, numSessions, myGlobals.maxNumLines,
 
6888
                         revertOrder, sortedColumn);
 
6889
 
 
6890
        printFooterHostLink();
 
6891
    } else {
 
6892
        if(el == NULL) {
 
6893
            printFlagedWarning("<I>No SCSI Sessions</I>");
 
6894
        }
 
6895
    }
 
6896
 
 
6897
    free (tmpTable);
 
6898
    return (printedSessions);
 
6899
}
 
6900
 
 
6901
/* ********************************** */
 
6902
 
 
6903
void printFCSessions (int actualDeviceId, int sortedColumn, int revertOrder,
 
6904
                      int pageNum, char *url, HostTraffic *el) {
 
6905
    int idx, i;
 
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;
 
6915
 
 
6916
    printHTMLheader("FibreChannel Sessions", 0, 0);
 
6917
 
 
6918
    if(!myGlobals.enableSessionHandling) {
 
6919
        printNotAvailable("-z or --disable-sessions");
 
6920
        return;
 
6921
    }
 
6922
    
 
6923
    tmpTable = (FCSession**)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numFcSessions*sizeof(FCSession *), "printFCSessions");
 
6924
    if(tmpTable == NULL)
 
6925
      return;
 
6926
 
 
6927
    for(i=strlen(url); i>0; i--)
 
6928
        if(url[i] == '?') {
 
6929
            url[i] = '\0';
 
6930
            break;
 
6931
        }
 
6932
      
 
6933
    urlFixupFromRFC1945Inplace(url);
 
6934
 
 
6935
    /*
 
6936
      Due to the way sessions are handled, sessions before those to
 
6937
      display need to be skipped
 
6938
    */
 
6939
 
 
6940
#ifdef CFG_MULTITHREADED
 
6941
    accessMutex(&myGlobals.fcSessionsMutex, "printFCSessions");
 
6942
#endif
 
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)) {
 
6949
                if ((el
 
6950
                     && ((session->initiator  == el)
 
6951
                         || (session->remotePeer == el)))
 
6952
                    || (el == NULL)) {
 
6953
                    tmpTable[numSessions++] = session;
 
6954
                }
 
6955
            }
 
6956
            session = session->next;
 
6957
        }
 
6958
    }
 
6959
 
 
6960
#ifdef CFG_MULTITHREADED
 
6961
    releaseMutex(&myGlobals.fcSessionsMutex);
 
6962
#endif
 
6963
 
 
6964
    if(numSessions <= 0) {
 
6965
        printNoDataYet ();
 
6966
        return;
 
6967
    }
 
6968
 
 
6969
    if(revertOrder) {
 
6970
        sign = "";
 
6971
        arrowGif = "&nbsp;" CONST_IMG_ARROW_UP;
 
6972
    } else {
 
6973
        sign = "-";
 
6974
        arrowGif = "&nbsp;" CONST_IMG_ARROW_DOWN;
 
6975
    }
 
6976
 
 
6977
    myGlobals.columnSort = sortedColumn;
 
6978
    qsort (tmpTable, numSessions, sizeof (FCSession **), cmpFcSessionsFctn);
 
6979
 
 
6980
    if (strcmp (url, CONST_FC_SESSIONS_HTML) == 0) {
 
6981
        if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s?col=%s", url, sign) < 0)
 
6982
            BufferTooShort();
 
6983
        if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s?col=", url) < 0)
 
6984
            BufferTooShort();
 
6985
    } else {
 
6986
        if(snprintf(htmlAnchor, sizeof(htmlAnchor), "<A HREF=/%s.html?col=%s", url, sign) < 0)
 
6987
            BufferTooShort();
 
6988
        if(snprintf(htmlAnchor1, sizeof(htmlAnchor1), "<A HREF=/%s.html?col=", url) < 0)
 
6989
            BufferTooShort();
 
6990
    }
 
6991
 
 
6992
    for (i = 1; i < 21; i++) {
 
6993
        if (abs(myGlobals.columnSort) == i) {
 
6994
            arrow[i] = arrowGif;
 
6995
            theAnchor[i] = htmlAnchor;
 
6996
        }
 
6997
        else {
 
6998
            arrow[i] = "";
 
6999
            theAnchor[i] = htmlAnchor1;
 
7000
        }
 
7001
    }
 
7002
 
 
7003
    printedSessions = skipSessions = 0;
 
7004
    for (idx = 0; idx < numSessions; idx++) {
 
7005
        Counter dataSent, dataRcvd;
 
7006
 
 
7007
        if(revertOrder)
 
7008
            session = tmpTable[numSessions-idx-1];
 
7009
        else
 
7010
            session = tmpTable[idx];
 
7011
 
 
7012
        if (session == NULL) {
 
7013
            /* Some update is in progress ? */
 
7014
            continue;
 
7015
        }
 
7016
        
 
7017
        if (printedSessions < myGlobals.maxNumLines) {
 
7018
            
 
7019
            if(el
 
7020
               && (session->initiator  != el)
 
7021
               && (session->remotePeer != el)) {
 
7022
                continue;
 
7023
            }
 
7024
 
 
7025
            if((skipSessions++) < pageNum*myGlobals.maxNumLines) {
 
7026
                continue;
 
7027
            }
 
7028
            
 
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&nbsp;Since%s</A></TH>\n"
 
7044
                              "<TH "TH_BG" "DARK_BG" rowspan=\"2\">%s19>Last&nbsp;Seen%s</A></TH>"
 
7045
                              "</TR>\n",
 
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]
 
7051
                        ) < 0)
 
7052
                    BufferTooShort();
 
7053
                
 
7054
                sendString (buf);
 
7055
                
 
7056
                if (snprintf (buf, sizeof (buf),
 
7057
                              "<TR "TR_ON">"
 
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]
 
7074
                        ) < 0)
 
7075
                    BufferTooShort ();
 
7076
                sendString (buf);
 
7077
 
 
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>"
 
7085
                              "</TR>\n",
 
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]
 
7092
                        ) < 0)
 
7093
                    BufferTooShort ();
 
7094
                sendString (buf);
 
7095
            }
 
7096
 
 
7097
            dataSent = session->bytesSent.value;
 
7098
            dataRcvd = session->bytesRcvd.value;
 
7099
            duration = session->lastSeen.tv_sec - session->firstSeen.tv_sec;
 
7100
            
 
7101
            /* Sanity check */
 
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>"
 
7122
                          "</TR>\n",
 
7123
                          getRowColor(),
 
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,
 
7135
                                      formatBuf[2], 32),
 
7136
                          formatBytes(session->fcpBytesRcvd.value, 1,
 
7137
                                      formatBuf[3], 32),
 
7138
                          formatBytes(session->fcElsBytesSent.value, 1,
 
7139
                                      formatBuf[4], 32),
 
7140
                          formatBytes(session->fcElsBytesRcvd.value, 1,
 
7141
                                      formatBuf[5], 32),
 
7142
                          formatBytes(session->fcDnsBytesSent.value, 1,
 
7143
                                      formatBuf[6], 32),
 
7144
                          formatBytes(session->fcDnsBytesRcvd.value, 1,
 
7145
                                      formatBuf[7], 32),
 
7146
                          formatBytes(session->ipfcBytesSent.value, 1,
 
7147
                                      formatBuf[8], 32),
 
7148
                          formatBytes(session->ipfcBytesRcvd.value, 1,
 
7149
                                      formatBuf[9], 32),
 
7150
                          formatBytes(session->fcSwilsBytesSent.value, 1,
 
7151
                                      formatBuf[10], 32),
 
7152
                          formatBytes(session->fcSwilsBytesRcvd.value, 1,
 
7153
                                      formatBuf[11], 32),
 
7154
                          formatBytes(session->otherBytesSent.value, 1,
 
7155
                                      formatBuf[12], 32),
 
7156
                          formatBytes(session->otherBytesRcvd.value, 1,
 
7157
                                      formatBuf[13], 32),
 
7158
                          formatTime((time_t *)&(session->firstSeen),
 
7159
                                     formatBuf[14], 32),
 
7160
                          formatTime((time_t *)&(session->lastSeen),
 
7161
                                     formatBuf[15], 32)
 
7162
                    ) < 0) BufferTooShort();
 
7163
            
 
7164
            sendString(buf);
 
7165
            printedSessions++;
 
7166
        }
 
7167
    }
 
7168
 
 
7169
    if (printedSessions > 0)  {
 
7170
        sendString("</TABLE>"TABLE_OFF"<P>\n");
 
7171
        sendString("</CENTER>\n");
 
7172
 
 
7173
        addPageIndicator(url, pageNum, numSessions, myGlobals.maxNumLines,
 
7174
                         revertOrder, sortedColumn);
 
7175
 
 
7176
        printFooterHostLink();
 
7177
    } else {
 
7178
        if(el == NULL) {
 
7179
            printFlagedWarning("<I>No FibreChannel Sessions</I>");
 
7180
        }
 
7181
    }
 
7182
    
 
7183
    free (tmpTable);
 
7184
}
 
7185
 
 
7186
/* ********************************** */
 
7187
 
 
7188
void printFcProtocolDistribution(int mode, int revertOrder)
 
7189
{
 
7190
    char buf[2*LEN_GENERAL_WORK_BUFFER], *sign;
 
7191
    float total, partialTotal, remainingTraffic;
 
7192
    float percentage;
 
7193
 
 
7194
    if(revertOrder)
 
7195
        sign = "";
 
7196
    else
 
7197
        sign = "-";
 
7198
 
 
7199
    total = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcBytes.value;
 
7200
 
 
7201
    if(total == 0)
 
7202
        return;
 
7203
    else {
 
7204
 
 
7205
        int numProtosFound = 0;
 
7206
        
 
7207
        printSectionTitle("Global FibreChannel Protocol Distribution");
 
7208
 
 
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&nbsp;Protocol</TH>"
 
7212
                   "<TH "TH_BG" WIDTH=50 "DARK_BG">Total&nbsp;Bytes</TH><TH "TH_BG" WIDTH=250 COLSPAN=2 "DARK_BG">"
 
7213
                   "Percentage</TH></TR>\n");
 
7214
 
 
7215
        remainingTraffic = 0;
 
7216
 
 
7217
        partialTotal  = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcFcpBytes.value;
 
7218
        if(partialTotal > 0) {
 
7219
            remainingTraffic += partialTotal;
 
7220
            percentage = ((float)(partialTotal*100))/((float)total);
 
7221
            numProtosFound++;
 
7222
            printTableEntry(buf, sizeof(buf), "SCSI",
 
7223
                            CONST_COLOR_1, partialTotal/1024, percentage);
 
7224
        }
 
7225
 
 
7226
        partialTotal  = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcFiconBytes.value;
 
7227
        if(partialTotal > 0) {
 
7228
            remainingTraffic += partialTotal;
 
7229
            percentage = ((float)(partialTotal*100))/((float)total);
 
7230
            numProtosFound++;
 
7231
            printTableEntry(buf, sizeof(buf), "FICON",
 
7232
                            CONST_COLOR_1, partialTotal/1024, percentage);
 
7233
        }
 
7234
        
 
7235
        partialTotal  = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcElsBytes.value;
 
7236
        if(partialTotal > 0) {
 
7237
            remainingTraffic += partialTotal;
 
7238
            percentage = ((float)(partialTotal*100))/((float)total);
 
7239
            numProtosFound++;
 
7240
            printTableEntry(buf, sizeof(buf), "ELS",
 
7241
                            CONST_COLOR_1, partialTotal/1024, percentage);
 
7242
        }
 
7243
 
 
7244
        partialTotal  = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcDnsBytes.value;
 
7245
        if(partialTotal > 0) {
 
7246
            remainingTraffic += partialTotal;
 
7247
            percentage = ((float)(partialTotal*100))/((float)total);
 
7248
            numProtosFound++;
 
7249
            printTableEntry(buf, sizeof(buf), "NS",
 
7250
                            CONST_COLOR_1, partialTotal/1024, percentage);
 
7251
        }
 
7252
 
 
7253
        
 
7254
        partialTotal  = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcIpfcBytes.value;
 
7255
        if(partialTotal > 0) {
 
7256
            remainingTraffic += partialTotal;
 
7257
            percentage = ((float)(partialTotal*100))/((float)total);
 
7258
            numProtosFound++;
 
7259
            printTableEntry(buf, sizeof(buf), "IP/FC",
 
7260
                            CONST_COLOR_1, partialTotal/1024, percentage);
 
7261
        }
 
7262
        
 
7263
        partialTotal  = (float)myGlobals.device[myGlobals.actualReportDeviceId].fcSwilsBytes.value;
 
7264
        if(partialTotal > 0) {
 
7265
            remainingTraffic += partialTotal;
 
7266
            percentage = ((float)(partialTotal*100))/((float)total);
 
7267
            numProtosFound++;
 
7268
            printTableEntry(buf, sizeof(buf), "SWILS",
 
7269
                            CONST_COLOR_1, partialTotal/1024, percentage);
 
7270
        }
 
7271
 
 
7272
        partialTotal  = (float)myGlobals.device[myGlobals.actualReportDeviceId].otherFcBytes.value;
 
7273
        if(partialTotal > 0) {
 
7274
            remainingTraffic += partialTotal;
 
7275
            percentage = ((float)(partialTotal*100))/((float)total);
 
7276
            numProtosFound++;
 
7277
            printTableEntry(buf, sizeof(buf), "Others",
 
7278
                            CONST_COLOR_1, partialTotal/1024, percentage);
 
7279
        }
 
7280
        
 
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");
 
7286
 
 
7287
        /* *********************** */
 
7288
 
 
7289
        sendString("<p>Note:This report includes broadcast packets</p>\n");
 
7290
        sendString("</CENTER>\n");
 
7291
    }
 
7292
}
 
7293
 
 
7294
/* ************************ */
 
7295
 
 
7296
#ifdef NOT_YET
 
7297
void printFcTrafficMatrix (u_short vsanId, u_char sent)
 
7298
{
 
7299
  int i, j, numEntries=0, numConsecutiveEmptyCells;
 
7300
  char buf[LEN_GENERAL_WORK_BUFFER];
 
7301
  short *activeHosts;
 
7302
  Counter minTraffic=(Counter)LONG_MAX, maxTraffic=0, avgTraffic;
 
7303
  Counter avgTrafficLow, avgTrafficHigh, tmpCounter;
 
7304
  TrafficEntry *entry;
 
7305
 
 
7306
  if(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix == NULL) {
 
7307
    printFlagedWarning("<I>Traffic matrix is not available for the selected network interface</I>");
 
7308
    return;
 
7309
  }
 
7310
 
 
7311
  /* Print a matrix, using just what the row/column header says: From -> To */
 
7312
  /* This is different from IP which prints a total */
 
7313
  if (vsanId) {
 
7314
      if(snprintf (buf, sizeof(buf), "FibreChannel Traffic Matrix For VSAN %d", vsanId) < 0)
 
7315
        BufferTooShort();
 
7316
  }
 
7317
  else {
 
7318
      if(snprintf (buf, sizeof(buf), "FibreChannel Traffic Matrix For VSAN") < 0)
 
7319
        BufferTooShort();
 
7320
  }
 
7321
  
 
7322
  printHTMLheader(buf, 0);
 
7323
 
 
7324
  activeHosts = (short*)mallocAndInitWithReportWarn(myGlobals.device[myGlobals.actualReportDeviceId].numHosts*sizeof(short), "printFcTrafficMatrix");
 
7325
  if(activeHosts == NULL)
 
7326
      return;
 
7327
 
 
7328
  for(i=1; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; i++) {
 
7329
 
 
7330
      activeHosts[i] = 0;
 
7331
      for(j=1; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts-1; j++) {
 
7332
          int id;
 
7333
 
 
7334
          id = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
 
7335
          entry = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[id];
 
7336
 
 
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)) {
 
7340
          }
 
7341
          else if ((entry != NULL) && (entry->vsanId == vsanId)) {
 
7342
              if ((entry->bytesSent.value) || (entry->bytesRcvd.value)) {
 
7343
                  activeHosts[i] = 1;
 
7344
                  numEntries++;
 
7345
                  break;
 
7346
              }
 
7347
          }
 
7348
      }
 
7349
 
 
7350
      /* Print column header if there is traffic sent from another host to this
 
7351
       * host
 
7352
       */
 
7353
      if(activeHosts[i] == 1) {
 
7354
          if(numEntries == 1) {
 
7355
              sendString("<CENTER>\n");
 
7356
              if (sent) 
 
7357
                  sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON"><TH "TH_BG" ALIGN=LEFT><SMALL>&nbsp;F&nbsp;"
 
7358
                             "&nbsp;&nbsp;To<br>&nbsp;r<br>&nbsp;o<br>&nbsp;m</SMALL></TH>\n");
 
7359
              else
 
7360
                  sendString(""TABLE_ON"<TABLE BORDER=1 "TABLE_DEFAULTS"><TR "TR_ON"><TH "TH_BG" ALIGN=LEFT><SMALL>&nbsp;B&nbsp;"
 
7361
                             "&nbsp;&nbsp;From<br>&nbsp;y<br></SMALL></TH>\n");
 
7362
          }
 
7363
 
 
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)
 
7366
              BufferTooShort();
 
7367
          sendString(buf);
 
7368
      }
 
7369
  }
 
7370
 
 
7371
  if(numEntries == 0) {
 
7372
    printNoDataYet();
 
7373
    free(activeHosts);
 
7374
    return;
 
7375
  } else
 
7376
    sendString("</TR>\n");
 
7377
 
 
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];
 
7383
          
 
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;
 
7390
              }
 
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;
 
7396
              }
 
7397
          }
 
7398
      }
 
7399
  }
 
7400
 
 
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 */
 
7404
 
 
7405
 
 
7406
  /* Print rows */
 
7407
  for(i=1; i<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; i++)
 
7408
    if(activeHosts[i] == 1) {
 
7409
      numConsecutiveEmptyCells=0;
 
7410
 
 
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)
 
7414
          BufferTooShort();
 
7415
      sendString(buf);
 
7416
 
 
7417
      for(j=1; j<myGlobals.device[myGlobals.actualReportDeviceId].numHosts; j++) {
 
7418
        int idx = i*myGlobals.device[myGlobals.actualReportDeviceId].numHosts+j;
 
7419
 
 
7420
        if ((i == j) &&
 
7421
            (strncmp (myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrixHosts[i]->hostNumFcAddress,
 
7422
                     "ff.ff.fd", sizeof ("ff.ff.fd")) != 0)) {
 
7423
            numConsecutiveEmptyCells++;
 
7424
        }
 
7425
        else if (activeHosts[j] == 1) {
 
7426
            if(myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx] == NULL)
 
7427
                numConsecutiveEmptyCells++;
 
7428
            else {
 
7429
                if(numConsecutiveEmptyCells > 0) {
 
7430
                    if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d>&nbsp;</TD>\n",
 
7431
                                numConsecutiveEmptyCells) < 0) BufferTooShort();
 
7432
                    sendString(buf);
 
7433
                    numConsecutiveEmptyCells = 0;
 
7434
                }
 
7435
 
 
7436
                if (sent) {
 
7437
                    tmpCounter = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx]->bytesSent.value;
 
7438
                }
 
7439
                else {
 
7440
                    tmpCounter = myGlobals.device[myGlobals.actualReportDeviceId].fcTrafficMatrix[idx]->bytesRcvd.value;
 
7441
                }
 
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)
 
7447
                    BufferTooShort();
 
7448
                sendString(buf);
 
7449
            }
 
7450
        }
 
7451
      }
 
7452
 
 
7453
      if(numConsecutiveEmptyCells > 0) {
 
7454
        if(snprintf(buf, sizeof(buf), "<TD "TD_BG" COLSPAN=%d>&nbsp;</TD>\n",
 
7455
                    numConsecutiveEmptyCells) < 0)
 
7456
          BufferTooShort();
 
7457
        sendString(buf);
 
7458
        numConsecutiveEmptyCells = 0;
 
7459
      }
 
7460
 
 
7461
      sendString("</TR>\n");
 
7462
    }
 
7463
 
 
7464
  sendString("</TABLE>"TABLE_OFF"\n<P>\n");
 
7465
  sendString("</CENTER>\n");
 
7466
  
 
7467
  printFooterHostLink();
 
7468
 
 
7469
  free(activeHosts);
 
7470
}
 
7471
#endif
 
7472
 
 
7473
/* ******************************************* */
 
7474
 
 
7475
void printVSANList(unsigned int deviceId) {
 
7476
  printHTMLheader("VSAN Traffic Statistics", 0, 0);
 
7477
 
 
7478
  if(deviceId > myGlobals.numDevices) {
 
7479
    printFlagedWarning("<I>Invalid device specified</I>");
 
7480
    return;
 
7481
  } else if(myGlobals.device[deviceId].vsanHash == NULL) {
 
7482
    printFlagedWarning("<I>No VSAN Traffic Information Available (yet).</I>");
 
7483
    return;
 
7484
  }
 
7485
 
 
7486
  dumpFcFabricElementHash(myGlobals.device[deviceId].vsanHash, "VSAN", 0, 1);
 
7487
}
 
7488
 
 
7489
/* ********************************** */
 
7490
 
 
7491
void drawVsanStatsGraph (unsigned int deviceId)
 
7492
{
 
7493
    char buf[LEN_GENERAL_WORK_BUFFER], vsanBuf[LEN_MEDIUM_WORK_BUFFER];
 
7494
    FcFabricElementHash **theHash;
 
7495
    FcFabricElementHash *tmpTable[MAX_ELEMENT_HASH];
 
7496
    int i, numVsans, j;
 
7497
    char vsanLabel[LEN_GENERAL_WORK_BUFFER];
 
7498
    
 
7499
    if(deviceId > myGlobals.numDevices) {
 
7500
        printFlagedWarning("<I>Invalid device specified</I>");
 
7501
        return;
 
7502
    } else if ((theHash = myGlobals.device[deviceId].vsanHash) == NULL) {
 
7503
          printHTMLheader("VSAN Summary", 0, 0);
 
7504
        printNoDataYet();
 
7505
        return;
 
7506
    }
 
7507
 
 
7508
    printHTMLheader("Top 10 VSANs", 0, 0);
 
7509
 
 
7510
    numVsans = 0;
 
7511
    memset (tmpTable, sizeof (FcFabricElementHash *)*MAX_ELEMENT_HASH, 0);
 
7512
 
 
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];
 
7518
        }
 
7519
    }
 
7520
 
 
7521
    myGlobals.columnSort = 3;
 
7522
    qsort (tmpTable, numVsans, sizeof (FcFabricElementHash **), cmpVsanFctn);
 
7523
 
 
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>"
 
7526
               "VSAN</TH>"
 
7527
               "<TH "TH_BG" "DARK_BG" WIDTH=75>Total&nbsp;Bytes</TH><TH "TH_BG" "DARK_BG" WIDTH=500 COLSPAN=2>"
 
7528
               "Percentage</TH></TR>\n");
 
7529
 
 
7530
 
 
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)
 
7535
              BufferTooShort();
 
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)));
 
7540
                             
 
7541
        }
 
7542
        
 
7543
        if (j >= MAX_VSANS_GRAPHED)
 
7544
            break;
 
7545
    }
 
7546
    sendString("</TABLE>"TABLE_OFF"<P>\n");
 
7547
            
 
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)
 
7553
        BufferTooShort();
 
7554
    sendString(buf);
 
7555
    
 
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)
 
7561
        BufferTooShort();
 
7562
    sendString(buf);
 
7563
}
 
7564
 
 
7565
/* ******************************************* */
 
7566