2
* Copyright (C) 1998-2001 Luca Deri <deri@ntop.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
#include "globals-report.h"
24
/* ****************************** */
26
static int icmpColumnSort = 0;
34
struct mtu_discovery {
40
struct ih_rdiscovery {
46
struct id_rdiscovery {
51
/* ****************************** */
53
static int sortICMPhosts(const void *_a, const void *_b) {
54
HostTraffic **a = (HostTraffic **)_a;
55
HostTraffic **b = (HostTraffic **)_b;
59
if(((*a) == NULL) && ((*b) != NULL)) {
60
traceEvent(TRACE_WARNING, "WARNING (1)\n");
62
} else if(((*a) != NULL) && ((*b) == NULL)) {
63
traceEvent(TRACE_WARNING, "WARNING (2)\n");
65
} else if(((*a) == NULL) && ((*b) == NULL)) {
66
traceEvent(TRACE_WARNING, "WARNING (3)\n");
70
switch(icmpColumnSort) {
72
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_ECHO] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_ECHO];
73
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_ECHO] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_ECHO];
74
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
77
case 12: /* Echo Reply */
78
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_ECHOREPLY] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_ECHOREPLY];
79
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_ECHOREPLY] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_ECHOREPLY];
80
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
84
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_UNREACH] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_UNREACH];
85
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_UNREACH] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_UNREACH];
86
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
90
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_REDIRECT] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_REDIRECT];
91
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_REDIRECT] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_REDIRECT];
92
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
96
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_ROUTERADVERT] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_ROUTERADVERT];
97
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_ROUTERADVERT] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_ROUTERADVERT];
98
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
102
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_TIMXCEED] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_TIMXCEED];
103
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_TIMXCEED] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_TIMXCEED];
104
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
108
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_PARAMPROB] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_PARAMPROB];
109
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_PARAMPROB] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_PARAMPROB];
110
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
114
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_MASKREQ] + (*a)->icmpInfo->icmpMsgSent[ICMP_MASKREPLY] +
115
(*a)->icmpInfo->icmpMsgRcvd[ICMP_MASKREQ]+ (*a)->icmpInfo->icmpMsgRcvd[ICMP_MASKREPLY];
116
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_MASKREQ] + (*b)->icmpInfo->icmpMsgSent[ICMP_MASKREPLY] +
117
(*b)->icmpInfo->icmpMsgRcvd[ICMP_MASKREQ]+ (*b)->icmpInfo->icmpMsgRcvd[ICMP_MASKREPLY];
118
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
123
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_SOURCE_QUENCH] + (*a)->icmpInfo->icmpMsgRcvd[ICMP_SOURCE_QUENCH];
124
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_SOURCE_QUENCH] + (*b)->icmpInfo->icmpMsgRcvd[ICMP_SOURCE_QUENCH];
125
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
129
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_TIMESTAMP] + (*a)->icmpInfo->icmpMsgSent[ICMP_TIMESTAMPREPLY] +
130
(*a)->icmpInfo->icmpMsgRcvd[ICMP_TIMESTAMP]+ (*a)->icmpInfo->icmpMsgRcvd[ICMP_TIMESTAMPREPLY];
131
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_TIMESTAMP] + (*b)->icmpInfo->icmpMsgSent[ICMP_TIMESTAMPREPLY] +
132
(*b)->icmpInfo->icmpMsgRcvd[ICMP_TIMESTAMP]+ (*b)->icmpInfo->icmpMsgRcvd[ICMP_TIMESTAMPREPLY];
133
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
137
n1 = (*a)->icmpInfo->icmpMsgSent[ICMP_INFO_REQUEST] + (*a)->icmpInfo->icmpMsgSent[ICMP_INFO_REPLY] +
138
(*a)->icmpInfo->icmpMsgRcvd[ICMP_INFO_REQUEST]+ (*a)->icmpInfo->icmpMsgRcvd[ICMP_INFO_REPLY];
139
n2 = (*b)->icmpInfo->icmpMsgSent[ICMP_INFO_REQUEST] + (*b)->icmpInfo->icmpMsgSent[ICMP_INFO_REPLY] +
140
(*b)->icmpInfo->icmpMsgRcvd[ICMP_INFO_REQUEST]+ (*b)->icmpInfo->icmpMsgRcvd[ICMP_INFO_REPLY];
141
if(n1 > n2) return(1); else if(n1 < n2) return(-1); else return(0);
146
accessMutex(&addressResolutionMutex, "addressResolution");
149
rc = strcasecmp((*a)->hostSymIpAddress, (*b)->hostSymIpAddress);
152
releaseMutex(&addressResolutionMutex);
159
/* ******************************* */
161
static void handleIcmpWatchHTTPrequest(char* url) {
162
char buf[1024], anchor[256], fileName[NAME_MAX] = "/tmp/ntop-icmpPlugin-XXXXXX";
164
char *pluginName = "<A HREF=/plugins/icmpWatch";
165
u_int i, revertOrder=0, num;
168
struct in_addr hostIpAddress;
169
char **lbls, *strtokState;
173
i = sizeof(float)*device[actualReportDeviceId].actualHashSize;
174
s = (float*)malloc(i); r = (float*)malloc(i);
175
memset(s, 0, i); memset(r, 0, i);
177
i = sizeof(char*)*device[actualReportDeviceId].actualHashSize;
181
i = sizeof(HostTraffic*)*device[actualReportDeviceId].actualHashSize;
182
hosts = (HostTraffic**)malloc(i);
184
for(i=0, num=0; i<device[actualReportDeviceId].actualHashSize; i++)
185
if((device[actualReportDeviceId].hash_hostTraffic[i] != NULL)
186
&& (device[actualReportDeviceId].hash_hostTraffic[i]->icmpInfo != NULL)) {
187
hosts[num++] = device[actualReportDeviceId].hash_hostTraffic[i];
190
hostIpAddress.s_addr = 0;
194
else if((url[0] == '-') || isdigit(url[0])) {
198
icmpColumnSort = atoi(&url[1]);
200
icmpColumnSort = atoi(url);
201
} else /* host=3240847503&icmp=3 */ {
205
if(strncmp(url, "chart", strlen("chart")) == 0) {
208
unsigned long sc[2] = { 0xf08080L, 0x4682b4L }; /* see clr[] in graph.c */
210
GDC_BGColor = 0xFFFFFFL; /* backgound color (white) */
211
GDC_LineColor = 0x000000L; /* line color (black) */
212
GDC_SetColor = &(sc[0]); /* assign set colors */
213
GDC_ytitle = "Packets";
215
for(i=0; i<num; i++) {
216
if(hosts[i] != NULL) {
219
s[tot] = 0, r[tot] = 0;
221
for(j=0; j<ICMP_MAXTYPE; j++) {
223
traceEvent(TRACE_INFO, "idx=%d/type=%d: %d/%d\n", i, j,
224
hosts[i]->icmpInfo->icmpMsgSent[j],
225
hosts[i]->icmpInfo->icmpMsgRcvd[j]);
227
s[tot] += (float)(hosts[i]->icmpInfo->icmpMsgSent[j]);
228
r[tot] += (float)(hosts[i]->icmpInfo->icmpMsgRcvd[j]);
231
lbls[tot++] = hosts[i]->hostSymIpAddress;
235
/* traceEvent(TRACE_INFO, "file=%s\n", fileName); */
237
fd = getNewRandomFile(fileName, NAME_MAX);
239
GDC_title = "ICMP Host Traffic";
240
/* The line below causes a crash on Solaris/SPARC (who knows why) */
242
GDC_ylabel_fmt = NULL;
243
out_graph(600, 450, /* width, height */
244
fd, /* open FILE pointer */
245
GDC_3DBAR, /* chart type */
246
tot, /* num points per data set */
247
lbls, /* X labels array of char* */
248
2, /* number of data sets */
249
s, r); /* dataset 2 */
253
sendHTTPHeader(MIME_TYPE_CHART_FORMAT, 0);
255
fd = fopen(fileName, "rb");
257
len = fread(tmpStr, sizeof(char), 255, fd);
259
sendStringLen(tmpStr, len);
270
strtok_r(url, "=", &strtokState);
272
tmpStr = strtok_r(NULL, "&", &strtokState);
273
hostIpAddress.s_addr = strtoul(tmpStr, (char **)NULL, 10);
275
traceEvent(TRACE_INFO, "-> %s [%u]\n", tmpStr, hostIpAddress.s_addr);
277
strtok_r(NULL, "=", &strtokState);
278
icmpId = atoi(strtok_r(NULL, "&", &strtokState));
281
sendHTTPHeader(HTTP_TYPE_HTML, 0);
282
printHTMLheader("ICMP Statistics", 0);
291
if(hostIpAddress.s_addr == 0)
292
sendString("<BR><CENTER><IMG SRC=\"/plugins/icmpWatch?chart\"></CENTER><P>\n");
295
sendString("<CENTER>\n");
296
sendString("<TABLE BORDER>\n");
297
if(snprintf(buf, sizeof(buf), "<TR><TH>%s?%s1>Host</A><br>[Pkt Sent/Rcvd]</TH>"
298
"<TH>%s?%s2>Echo Req.</A></TH>"
299
"<TH>%s?%s12>Echo Reply</A></TH>"
300
"<TH>%s?%s3>Unreach</A></TH>"
301
"<TH>%s?%s4>Redirect</A></TH>"
302
"<TH>%s?%s5>Router<br>Advert.</A></TH>"
303
"<TH>%s?%s6>Time<br>Exceeded</A></TH>"
304
"<TH>%s?%s7>Param.<br>Problem</A></TH>"
305
"<TH>%s?%s8>Network<br>Mask</A></TH>"
306
"<TH>%s?%s9>Source<br>Quench</A></TH>"
307
"<TH>%s?%s10>Timestamp</A></TH>"
308
"<TH>%s?%s11>Info</A></TH>"
321
pluginName, sign) < 0)
322
traceEvent(TRACE_ERROR, "Buffer overflow!");
325
quicksort(hosts, num, sizeof(HostTraffic **), sortICMPhosts);
328
if(hosts[i] != NULL) {
338
if(snprintf(buf, sizeof(buf), "<TR %s> %s",
340
makeHostLink(hosts[idx], LONG_FORMAT, 0, 0)) < 0)
341
traceEvent(TRACE_ERROR, "Buffer overflow!");
344
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s/%s</TD>",
345
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->icmpMsgSent[ICMP_ECHO])),
346
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_ECHO]))) < 0)
347
traceEvent(TRACE_ERROR, "Buffer overflow!");
350
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s/%s</TD>",
351
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->icmpMsgSent[ICMP_ECHOREPLY])),
352
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_ECHOREPLY]))) < 0)
353
traceEvent(TRACE_ERROR, "Buffer overflow!");
357
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_UNREACH]+
358
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_UNREACH];
362
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>",
364
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
365
icmpMsgSent[ICMP_UNREACH]),
366
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
367
icmpMsgRcvd[ICMP_UNREACH]),
369
traceEvent(TRACE_ERROR, "Buffer overflow!");
373
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_REDIRECT]+
374
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_REDIRECT];
379
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
380
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
381
icmpMsgSent[ICMP_REDIRECT]),
382
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
383
icmpMsgRcvd[ICMP_REDIRECT]),
384
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
387
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_ROUTERADVERT]+
388
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_ROUTERADVERT];
392
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
393
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
394
icmpMsgSent[ICMP_ROUTERADVERT]),
395
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
396
icmpMsgRcvd[ICMP_ROUTERADVERT]),
397
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
400
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_TIMXCEED]+
401
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_TIMXCEED];
405
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
406
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
407
icmpMsgSent[ICMP_TIMXCEED]),
408
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
409
icmpMsgRcvd[ICMP_TIMXCEED]),
410
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
413
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_PARAMPROB]+
414
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_PARAMPROB];
418
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
419
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
420
icmpMsgSent[ICMP_PARAMPROB]),
421
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
422
icmpMsgRcvd[ICMP_PARAMPROB]),
423
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
426
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_MASKREQ]+
427
hosts[idx]->icmpInfo->icmpMsgSent[ICMP_MASKREPLY]+
428
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_MASKREQ]+
429
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_MASKREPLY];
434
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
435
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->
436
icmpMsgSent[ICMP_MASKREQ]+
437
hosts[idx]->icmpInfo->icmpMsgSent[ICMP_MASKREPLY])),
438
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->
439
icmpMsgRcvd[ICMP_MASKREQ]+
440
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_MASKREPLY])),
441
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
444
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_SOURCE_QUENCH]+
445
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_SOURCE_QUENCH];
449
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
450
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
451
icmpMsgSent[ICMP_SOURCE_QUENCH]),
452
formatPkts((TrafficCounter)hosts[idx]->icmpInfo->
453
icmpMsgRcvd[ICMP_SOURCE_QUENCH]),
454
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
457
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_TIMESTAMP]+
458
hosts[idx]->icmpInfo->icmpMsgSent[ICMP_TIMESTAMPREPLY]+
459
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_TIMESTAMP]+
460
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_TIMESTAMPREPLY];
464
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
465
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->
466
icmpMsgSent[ICMP_TIMESTAMP]+
467
hosts[idx]->icmpInfo->icmpMsgSent[ICMP_TIMESTAMPREPLY])),
468
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->
469
icmpMsgRcvd[ICMP_TIMESTAMP]+
470
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_TIMESTAMPREPLY])),
471
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
474
tot=hosts[idx]->icmpInfo->icmpMsgSent[ICMP_INFO_REQUEST]+
475
hosts[idx]->icmpInfo->icmpMsgSent[ICMP_INFO_REPLY]+
476
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_INFO_REQUEST]+
477
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_INFO_REPLY];
481
if(snprintf(buf, sizeof(buf), "<TD ALIGN=center>%s%s/%s%s</TD>", anchor,
482
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->
483
icmpMsgSent[ICMP_INFO_REQUEST]+
484
hosts[idx]->icmpInfo->icmpMsgSent[ICMP_INFO_REPLY])),
485
formatPkts((TrafficCounter)(hosts[idx]->icmpInfo->
486
icmpMsgRcvd[ICMP_INFO_REQUEST]+
487
hosts[idx]->icmpInfo->icmpMsgRcvd[ICMP_INFO_REPLY])),
488
postAnchor) < 0) traceEvent(TRACE_ERROR, "Buffer overflow!");
491
sendString("</TR>\n");
494
sendString("</TABLE>\n");
496
sendString("<p></CENTER>\n");
506
/* ****************************** */
508
static void termIcmpFunct(void) {
509
traceEvent(TRACE_INFO, "Thanks for using icmpWatch..."); fflush(stdout);
510
traceEvent(TRACE_INFO, "Done.\n"); fflush(stdout);
513
/* ****************************** */
515
static PluginInfo icmpPluginInfo[] = {
517
"This plugin handles ICMP packets",
519
"<A HREF=http://luca.ntop.org/>L.Deri</A>",
520
"icmpWatch", /* http://<host>:<port>/plugins/icmpWatch */
522
NULL, /* no special startup after init */
523
termIcmpFunct, /* TermFunc */
524
NULL, /* PluginFunc */
525
handleIcmpWatchHTTPrequest,
527
NULL /* no capture */
531
/* ***************************************** */
533
/* Plugin entry fctn */
535
PluginInfo* icmpPluginEntryFctn(void) {
537
PluginInfo* PluginEntryFctn(void) {
539
traceEvent(TRACE_INFO, "Welcome to %s. (C) 1999 by Luca Deri.\n",
540
icmpPluginInfo->pluginName);
542
return(icmpPluginInfo);