3
* Copyright (C) 2001 Luca Deri <deri@ntop.org>
4
* Copyright (C) 2002 Walter Brock <walterbrock@netscape.net>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#include "globals-report.h"
26
/* ***** f o r w a r d ***** */
28
void printPdaData(HostTraffic* tmpTable[MAX_PDA_HOST_TABLE], u_int numEntries);
29
void printPdaSummaryData(void);
30
static void termPdaFunct(u_char termNtop /* 0=term plugin, 1=term ntop */);
31
static void handlePDArequest(char* url);
33
/* ****************************** */
35
static PluginInfo PDAPluginInfo[] = {
37
VERSION, /* current ntop version */
39
"This plugin produces a minimal ntop report, suitable for display on a pda",
41
"<a class=mailto href=\"mailto:walterbrock@netscape.net\">W. Brock</A>",
42
"PDAPlugin", /* http://<host>:<port>/plugins/PDAPlugin */
43
0, /* Active by default */
45
0, /* Inactive setup */
46
NULL, /* no special startup after init */
47
termPdaFunct, /* TermFunc */
48
NULL, /* PluginFunc */
49
handlePDArequest, /* http request handler */
50
NULL, /* no host creation/deletion handle */
51
NULL, /* BPF Filter */
53
NULL /* no extra pages */
57
/* ****************************** */
58
/* Plugin entry fctn */
59
#ifdef MAKE_STATIC_PLUGIN
60
PluginInfo* wapPluginEntryFctn(void)
62
PluginInfo* PluginEntryFctn(void)
65
traceEvent(CONST_TRACE_ALWAYSDISPLAY, "PDA: Welcome to %s. (C) 2001-2005 by L.Deri and W.Brock",
66
PDAPluginInfo->pluginName);
68
return(PDAPluginInfo);
71
/* ********************** */
73
static void printHtmlNotFoundError(void) {
74
sendString("Unknown request");
77
/* ********************** */
79
static int cmpPdaFctnSent(const void *_a, const void *_b) {
80
HostTraffic **a = (HostTraffic **)_a;
81
HostTraffic **b = (HostTraffic **)_b;
82
TrafficCounter a_, b_;
84
if((a == NULL) && (b != NULL)) {
85
traceEvent(CONST_TRACE_WARNING, "cmpPdaFctnSent() (1)");
87
} else if((a != NULL) && (b == NULL)) {
88
traceEvent(CONST_TRACE_WARNING, "cmpPdaFctnSent() (2)");
90
} else if((a == NULL) && (b == NULL)) {
91
traceEvent(CONST_TRACE_WARNING, "cmpPdaFctnSent() (3)");
99
if(a_.value < b_.value)
101
else if (a_.value > b_.value)
107
static int cmpPdaFctnRcvd(const void *_a, const void *_b) {
108
HostTraffic **a = (HostTraffic **)_a;
109
HostTraffic **b = (HostTraffic **)_b;
110
TrafficCounter a_, b_;
112
if((a == NULL) && (b != NULL)) {
113
traceEvent(CONST_TRACE_WARNING, "cmpPdaFctnRcvd() (1)");
115
} else if((a != NULL) && (b == NULL)) {
116
traceEvent(CONST_TRACE_WARNING, "cmpPdaFctnRcvd() (2)");
118
} else if((a == NULL) && (b == NULL)) {
119
traceEvent(CONST_TRACE_WARNING, "cmpPdaFctnRcvd() (3)");
124
a_ = (*a)->bytesRcvd;
125
b_ = (*b)->bytesRcvd;
127
if(a_.value < b_.value)
129
else if (a_.value > b_.value)
135
/* ********************** */
137
void printPdaData(HostTraffic* tmpTable[MAX_PDA_HOST_TABLE], u_int numEntries) {
142
char hostLinkBuf[LEN_GENERAL_WORK_BUFFER];
144
char buf[LEN_GENERAL_WORK_BUFFER];
147
sendString(" <table ");
148
sendString((myGlobals.runningPref.w3c == TRUE) ? "" : "columns=\"2\" ");
149
sendString("align=\"left\">\n");
150
sendString(" <tr><td><b><u>Top Sending Hosts</u></b></td><td><b><u>Total</u></b></td></tr>\n");
153
qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpPdaFctnSent);
155
for(idx=0; idx<numEntries; idx++) {
159
tmpName = getHostName(el, 0, hostLinkBuf, sizeof(hostLinkBuf));
160
tmpName = el->hostNumIpAddress;
161
strncpy(linkName, el->hostNumIpAddress, sizeof(linkName));
163
if((strcmp(tmpName, "0.0.0.0") == 0) || (tmpName[0] == '\0')){
164
tmpName = el->ethAddressString;
165
strncpy(linkName, el->ethAddressString, sizeof(linkName));
166
for(i=0; linkName[i] != '\0'; i++)
167
if(linkName[i] == ':')
171
safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf),
172
"<tr><td><a href=\"/%s.html\">%s</a></td>"
173
"<td>%s</td></tr>\n",
175
formatBytes(el->bytesSent.value, 1, formatBuf, sizeof(formatBuf)));
179
sendString("</table>\n"
183
sendString(" <table ");
184
sendString((myGlobals.runningPref.w3c == TRUE) ? "" : "columns=\"2\" ");
185
sendString("align=\"left\">\n");
186
sendString(" <tr><td><b><u>Top Receiving Hosts</u></b></td><td><b><u>Total</u></b></td></tr>\n");
189
qsort(tmpTable, numEntries, sizeof(HostTraffic*), cmpPdaFctnRcvd);
191
for(idx=0; idx<numEntries; idx++) {
195
tmpName = getHostName(el, 0, hostLinkBuf, sizeof(hostLinkBuf));
196
tmpName = el->hostNumIpAddress;
197
strncpy(linkName, el->hostNumIpAddress, sizeof(linkName));
199
if((strcmp(tmpName, "0.0.0.0") == 0) || (tmpName[0] == '\0')){
200
tmpName = el->ethAddressString;
201
strncpy(linkName, el->ethAddressString, sizeof(linkName));
202
for(i=0; linkName[i] != '\0'; i++)
203
if(linkName[i] == ':')
206
safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf),
207
"<tr><td><a href=\"/%s.html\">%s</a></td>"
208
"<td>%s</td></tr>\n",
210
formatBytes(el->bytesRcvd.value, 1, formatBuf, sizeof(formatBuf)));
214
sendString("</table>\n");
215
sendString("<br><br>\n");
218
/* ********************** */
220
void printPdaSummaryData(void) {
224
char buf[LEN_GENERAL_WORK_BUFFER];
225
Counter unicastPkts=0;
227
sendString(" <table ");
228
sendString((myGlobals.runningPref.w3c == TRUE) ? "" : "columns=\"2\" ");
229
sendString("align=\"left\">\n");
230
sendString(" <tr><td><b><u>Stats</u></b></td><td><b><u>Total</u></b></td></tr>\n");
234
safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf),"<tr><td>Sampling Time</td>"
235
"<td>%s</td></tr>\n",
236
formatSeconds((long)(myGlobals.actTime-myGlobals.initialSniffTime), formatBuf, sizeof(formatBuf)));
241
diff = myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value - myGlobals.device[myGlobals.actualReportDeviceId].broadcastPkts.value -
242
myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value;
245
unicastPkts = 0; /* It shouldn't happen */
249
if(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value <= 0)
250
myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value = 1;
252
safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf),"<tr><td>Total</td><td>%s</td></tr>\n",
253
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value, formatBuf, sizeof(formatBuf)));
256
safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf),"<tr><td>Unicast</td>"
257
"<td>%s [%.1f%%]</td></tr>\n",
258
formatPkts(unicastPkts, formatBuf, sizeof(formatBuf)),
259
(float)(100*unicastPkts)/(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value);
261
safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf),"<tr><td>Broadcast</td>"
262
"<td>%s [%.1f%%]</td></tr>\n",
263
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].broadcastPkts.value, formatBuf, sizeof(formatBuf)),
264
(float)(100*myGlobals.device[myGlobals.actualReportDeviceId].broadcastPkts.value)
265
/(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value);
268
if(myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value > 0) {
269
safe_snprintf(__FILE__, __LINE__, buf, sizeof(buf),"<tr><td>Multicast</td>"
270
"<td>%s [%.1f%%]</td></tr>\n",
271
formatPkts(myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value, formatBuf, sizeof(formatBuf)),
272
(float)(100*myGlobals.device[myGlobals.actualReportDeviceId].multicastPkts.value)
273
/(float)myGlobals.device[myGlobals.actualReportDeviceId].ethernetPkts.value);
278
sendString("</table>\n");
280
/* ********************** */
282
static void printHtmlIndex(void) {
283
u_int idx, numEntries=0;
285
HostTraffic* tmpTable[MAX_PDA_HOST_TABLE];
290
deviceId = (int)_deviceId;
293
actualDeviceId = getActualInterface(deviceId); */
295
for(idx=1; idx<myGlobals.device[myGlobals.actualReportDeviceId].actualHashSize; idx++)
296
if(((el = myGlobals.device[myGlobals.actualReportDeviceId].hash_hostTraffic[idx]) != NULL)
297
&& (!broadcastHost(el))
298
&& (numEntries < MAX_PDA_HOST_TABLE))
299
tmpTable[numEntries++]=el;
302
printPdaData(tmpTable, numEntries);
304
sendString(" \n");
306
sendString("</td></tr>\n"
309
printPdaSummaryData();
313
/* ********************** */
315
static void printHtmlHostInfo(char *host _UNUSED_) {
316
sendString("Data for host ");
318
sendString("<br>Currently this function is not available");
322
/* ********************** */
324
static void handlePDArequest(char* url) {
326
sendHTTPHeader(FLAG_HTTP_TYPE_HTML, BITFLAG_HTTP_NO_CACHE_CONTROL | BITFLAG_HTTP_MORE_FIELDS, 1);
327
sendString((myGlobals.runningPref.w3c == TRUE) ? CONST_W3C_DOCTYPE_LINE_32 "\n" : "");
328
sendString("<html>\n"
330
sendString((myGlobals.runningPref.w3c == TRUE) ? CONST_W3C_CHARTYPE_LINE "\n" : "");
331
sendString("<meta http-equiv=REFRESH content=\"240\">\n"
332
"<title>ntop for PDAs</title>\n");
333
/* sendString("<link rel=stylesheet href=\"/stylepda.css\" type=\"text/css\">\n"); */
334
sendString("</head>\n"
336
"<b>ntop for PDAs</b>\n"
338
sendString("<table ");
339
sendString((myGlobals.runningPref.w3c == TRUE) ? "" : "columns=\"1\" ");
340
sendString("align=\"left\">\n");
341
sendString("<tr><td>\n");
345
|| (strncmp(url, CONST_INDEX_HTML,
346
strlen(CONST_INDEX_HTML)) == 0)) {
348
} else if(strncmp(url, CONST_HOST_HTML, strlen(CONST_HOST_HTML)) == 0)
349
printHtmlHostInfo(&url[strlen(CONST_HOST_HTML)+1]);
351
printHtmlNotFoundError();
353
sendString("</td></tr>\n"
359
/* ****************************** */
361
static void termPdaFunct(u_char termNtop /* 0=term plugin, 1=term ntop */) {
362
traceEvent(CONST_TRACE_INFO, "PDA: Thanks for using ntop PDA plugin");
363
traceEvent(CONST_TRACE_ALWAYSDISPLAY, "PDA: Done");